Cleanup connection.c

This commit is contained in:
YohannDR 2024-10-03 12:19:55 +02:00
parent 848cacbf3f
commit f611c47164
23 changed files with 802 additions and 644 deletions

View File

@ -21,6 +21,6 @@ void ConnectionLoadDoors(void);
void ConnectionLockHatchesWithTimer(void);
void ConnectionCheckHatchLockEvents(void);
void ConnectionCheckPlayCutsceneDuringTransition(u8 area, u8 dstRoomPlusOne);
void ConnectionCheckPlayCutsceneDuringElevator(void);
void ConnectionCheckPlayCutsceneDuringAreaConnection(void);
#endif /* CONNECTION_H */

View File

@ -147,6 +147,7 @@
#define CLIP_BEHAVIOR_GROUND_EFFECT_UNUSED1 0x55
#define CLIP_BEHAVIOR_GROUND_EFFECT_UNUSED2 0x56
#define CLIP_BEHAVIOR_GROUND_EFFECT_UNUSED3 0x57
#define CLIP_BEHAVIOR_NO_DOOR 0x7F
#define CLIP_BEHAVIOR_GRAY_DOOR 0x80
#define CLIP_BEHAVIOR_REGULAR_DOOR 0x81
#define CLIP_BEHAVIOR_MISSILE_DOOR 0x82

View File

@ -17,54 +17,89 @@ enum Area {
AREA_DEBUG_3,
AREA_DEBUG_4,
AREA_END,
AREA_COUNT,
};
#define AREA_NONE UCHAR_MAX
#define DOOR_TYPE_NONE 0x0
#define DOOR_TYPE_AREA_CONNECTION 0x1
#define DOOR_TYPE_NO_HATCH 0x2
#define DOOR_TYPE_OPEN_HATCH 0x3
#define DOOR_TYPE_CLOSED_HATCH 0x4
#define DOOR_TYPE_REMOVE_MOTHER_SHIP 0x5
#define DOOR_TYPE_SET_MOTHER_SHIP 0x6
#define DOOR_TYPE_NO_FLAGS 0xF
#define DOOR_TYPE_EXISTS 0x10
#define DOOR_TYPE_LOAD_EVENT_BASED_ROOM 0x20
#define DOOR_TYPE_DISPLAYS_ROOM_LOCATION 0x40
enum DoorType {
DOOR_TYPE_NONE,
DOOR_TYPE_AREA_CONNECTION,
DOOR_TYPE_NO_HATCH,
DOOR_TYPE_OPEN_HATCH,
DOOR_TYPE_CLOSED_HATCH,
DOOR_TYPE_REMOVE_MOTHER_SHIP,
DOOR_TYPE_SET_MOTHER_SHIP,
#define HATCH_NONE 0x0
#define HATCH_UNUSED 0x1
#define HATCH_NORMAL 0x2
#define HATCH_MISSILE 0x3
#define HATCH_SUPER_MISSILE 0x4
#define HATCH_POWER_BOMB 0x5
#define HATCH_LOCKED 0x6
#define HATCH_LOCKED_AND_LOCK_DESTINATION 0x7
DOOR_TYPE_NO_FLAGS = (1 << 4) - 1,
#define HATCH_ACTION_CHECKING_OPENED 0x0
#define HATCH_ACTION_SETTING_SOURCE_AND_DESTINATION 0x1
#define HATCH_ACTION_SETTING_SOURCE 0x2
DOOR_TYPE_EXISTS = (1 << 4),
DOOR_TYPE_LOAD_EVENT_BASED_ROOM = (1 << 5),
DOOR_TYPE_DISPLAYS_ROOM_LOCATION = (1 << 6)
};
#define HATCH_OPENING_ACTION_NOT_OPENING 0x0
#define HATCH_OPENING_ACTION_OPENING 0x1
#define HATCH_OPENING_ACTION_LOCKED 0x2
enum HatchType {
HATCH_NONE,
HATCH_UNUSED,
HATCH_NORMAL,
HATCH_MISSILE,
HATCH_SUPER_MISSILE,
HATCH_POWER_BOMB,
HATCH_LOCKED,
HATCH_LOCKED_NAVIGATION,
HATCH_COUNT
};
enum HatchState {
HATCH_STATE_CLOSED,
HATCH_STATE_OPENING,
HATCH_STATE_OPENED,
HATCH_STATE_CLOSING,
};
enum HatchLockState {
HATCH_LOCK_STATE_UNLOCKED,
HATCH_LOCK_STATE_LOCKED,
HATCH_LOCK_STATE_PERMA_LOCKED,
};
enum HatchAction {
HATCH_ACTION_CHECKING_OPENED,
HATCH_ACTION_SETTING_SOURCE_AND_DESTINATION,
HATCH_ACTION_SETTING_SOURCE
};
enum HatchOpeningAction {
HATCH_OPENING_ACTION_NOT_OPENING,
HATCH_OPENING_ACTION_OPENING,
HATCH_OPENING_ACTION_LOCKED
};
enum HatchLockEventType {
HATCH_LOCK_EVENT_TYPE_AFTER,
HATCH_LOCK_EVENT_TYPE_BEFORE,
HATCH_LOCK_EVENT_TYPE_AFTER_UNLOCKEABLE,
HATCH_LOCK_EVENT_TYPE_BEFORE_UNLOCKEABLE,
};
enum ElevatorRoute {
ELEVATOR_ROUTE_NONE,
ELEVATOR_ROUTE_CRATERIA_TO_BRINSTAR,
ELEVATOR_ROUTE_BRINSTAR_TO_NORFAIR,
ELEVATOR_ROUTE_BRINSTAR_TO_KRAID,
ELEVATOR_ROUTE_NORFAIR_TO_RIDLEY,
ELEVATOR_ROUTE_BRINSTAR_TO_TOURIAN,
ELEVATOR_ROUTE_CRATERIA_TO_TOURIAN,
ELEVATOR_ROUTE_CRATERIA_TO_NORFAIR,
ELEVATOR_ROUTE_CRATERIA_TO_TOURIAN_2,
ELEVATOR_ROUTE_COUNT
};
#define ELEVATOR_DIRECTION_DOWN 1
#define ELEVATOR_DIRECTION_UP -1
#define HATCH_VERTICAL_SIZE 4
#define ELEVATOR_ROUTE_NONE 0x0
#define ELEVATOR_ROUTE_CRATERIA_TO_BRINSTAR 0x1
#define ELEVATOR_ROUTE_BRINSTAR_TO_NORFAIR 0x2
#define ELEVATOR_ROUTE_BRINSTAR_TO_KRAID 0x3
#define ELEVATOR_ROUTE_NORFAIR_TO_RIDLEY 0x4
#define ELEVATOR_ROUTE_BRINSTAR_TO_TOURIAN 0x5
#define ELEVATOR_ROUTE_CRATERIA_TO_TOURIAN 0x6
#define ELEVATOR_ROUTE_CRATERIA_TO_NORFAIR 0x7
#define ELEVATOR_ROUTE_CRATERIA_TO_TOURIAN_2 0x8
#define ELEVATOR_DIRECTION_DOWN 0x1
#define ELEVATOR_DIRECTION_UP -0x1
#endif /* CONNECTION_CONSTANTS_H */
#endif /* CONNECTION_CONSTANTS_H */

View File

@ -4,6 +4,7 @@
#include "types.h"
#include "constants/clipdata.h"
#include "constants/connection.h"
#include "constants/game_state.h"
#include "structs/block.h"
@ -29,7 +30,7 @@ extern const struct BombChainReverseData sBombChainReverseData[8];
extern const struct TankBehavior sTankBehaviors[MAX_AMOUNT_OF_TANK_TYPES];
extern const u16 sHatchBehaviors[MAX_AMOUNT_OF_HATCH_TYPES][2];
extern const u16 sHatchBehaviors[HATCH_COUNT][2];
extern const u16 sBldalphaValuesForClipdata[11];

View File

@ -3,6 +3,8 @@
#include "types.h"
#include "constants/connection.h"
#include "structs/clipdata.h"
#include "structs/scroll.h"
@ -10,7 +12,7 @@ extern const u16 sMovementClipdataValues[16];
extern const u16 sHazardsDefinitions[8][2];
extern const u16 sHazardClipdataValues[4];
extern const u8 sGroundEffectsClipdataValues[8];
extern const struct ElevatorPair sElevatorRoomPairs[9];
extern const struct ElevatorPair sElevatorRoomPairs[ELEVATOR_ROUTE_COUNT];
extern const u8 sScroll_Empty[11];
extern const struct CameraScrollVelocityCaps sScrollVelocityCaps[3];

View File

@ -31,7 +31,7 @@ extern const struct RoomEntryROM* const sAreaRoomEntryPointers[MAX_AMOUNT_OF_ARE
extern const s8 sWaterLoopCounterArray[8][2];
extern const u8* const * const sAreaScrollPointers[AREA_END];
extern const u8* const * const sAreaScrollPointers[AREA_COUNT];
extern const BlockFunc_T sNonReformDestroyFunctionPointers[5];

View File

@ -3,27 +3,29 @@
#include "types.h"
#include "constants/connection.h"
#include "structs/connection.h"
// 360130
extern const u8 sHatchTypeTable[MAX_AMOUNT_OF_HATCH_TYPES];
extern const u8 sHatchTypeTable[HATCH_COUNT];
extern const struct HatchLockEvent sHatchLockEventsBrinstar[1];
extern const struct HatchLockEvent sHatchLockEventsKraid[1];
extern const struct HatchLockEvent sHatchLockEventsNorfair[2];
extern const struct HatchLockEvent sHatchLockEventsCrateria[2];
extern const struct HatchLockEvent sHatchLockEventsChozodia[15];
extern const u8 sEventBasedConnections[MAX_AMOUNT_OF_EVENT_BASED_CONNECTIONS][4];
extern const u8 sEventBasedConnections[41][4];
extern const u8 sAreaConnections[26][3];
extern const u8 sAreaConnections[][AREA_CONNECTION_FIELD_COUNT];
extern const u8 sHatchesAnimationDurationCounter[6];
extern const u16 sHatchesTilemapValues[MAX_AMOUNT_OF_HATCH_TYPES];
extern const u16 sHatchesTilemapValues[HATCH_COUNT];
extern const u16 sNumberOfHatchLockEventsPerArea[MAX_AMOUNT_OF_AREAS];

View File

@ -22,7 +22,7 @@ extern u16 sPauseScreenCompletionInfoOamData[6][5];
extern const u8* const sStatusScreenFlagsOrderPointers[4];
extern const u32* const sMinimapDataPointers[AREA_END];
extern const u32* const sMinimapDataPointers[AREA_COUNT];
extern const u32 sExploredMinimapBitFlags[32];
extern const MinimapFunc_T sMinimapTilesCopyGfxFunctionPointers[4];

View File

@ -40,6 +40,9 @@
#define C_S8_2_S16(value) ((value) & 0x80 ? 0x100 + (value) : (value))
#define C_S9_2_S16(value) ((value) & 0x100 ? 0x200 + (value) : (value))
#define CAST_TO_ARRAY(type, sizes, ptr) (*((type (*)sizes)((ptr))))
#define OPPOSITE_DIRECTION(dir) ((dir) ^ (KEY_RIGHT | KEY_LEFT))
#define ARRAY_SIZE(a) ((s32)(sizeof((a)) / sizeof((a)[0])))
#define ARRAY_ACCESS(a, o) (a[(u32)(o) % ARRAY_SIZE(a)])

View File

@ -2,6 +2,7 @@
#define CONNECTION_STRUCT_H
#include "types.h"
#include "macros.h"
// Structs
@ -27,7 +28,7 @@ struct EventBasedConnection {
struct HatchLockEvent {
u8 room;
u8 event;
u8 isBefore;
u8 type;
u8 hatchesToLock_0:1;
u8 hatchesToLock_1:1;
u8 hatchesToLock_2:1;
@ -53,7 +54,7 @@ struct HatchData {
u16 facingRight:1;
u16 securityLevel:3; // Left over from fusion
/* 1 */
u8 opening:2;
u8 state:2;
u16 locked:2;
u16 flashingTimer:4;
/* 2 */
@ -75,10 +76,10 @@ struct LastElevatorUsed {
struct HatchesState {
s8 unlocking;
s8 unk;
s8 navigationDoorsUnlocking;
u16 hatchesLockedWithTimer;
u16 hatchesLockedWithEvent;
u16 unk2;
u16 hatchesLockedWithEventUnlockeable;
};
struct HatchFlashingAnimation {
@ -90,12 +91,27 @@ struct HatchFlashingAnimation {
s8 navigation_paletteRow;
};
enum AreaConnectionField {
AREA_CONNECTION_FIELD_SOURCE_AREA,
AREA_CONNECTION_FIELD_SOURCE_DOOR,
AREA_CONNECTION_FIELD_DESTINATION_AREA,
AREA_CONNECTION_FIELD_COUNT
};
enum EventBasedConnectionField {
EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA,
EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR,
EVENT_BASED_CONNECTION_FIELD_EVENT,
EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR,
EVENT_BASED_CONNECTION_FIELD_COUNT,
};
#define MAX_AMOUNT_OF_HATCHES 16
#define MAX_AMOUNT_OF_AREAS 8
#define MAX_AMOUNT_OF_HATCH_TYPES 8
#define MAX_AMOUNT_OF_EVENT_BASED_CONNECTIONS 41
extern u32 gHatchesOpened[MAX_AMOUNT_OF_AREAS][16];
#define gHatchesOpened CAST_TO_ARRAY(u32, [MAX_AMOUNT_OF_AREAS][8], EWRAM_BASE + 0x37C00)
extern u8 gWhichBGPositionIsWrittenToBG3OFS;
extern struct Coordinates gDoorPositionStart;

View File

@ -33,7 +33,6 @@ SECTIONS {
. = 0x00035c00; gNeverReformBlocks = .;
. = 0x00036c00; gItemsCollected = .;
. = 0x00037400; gVisitedMinimapTiles = .;
. = 0x00037c00; gHatchesOpened = .;
. = 0x00037e00; gEventsTriggered = .;
. = 0x00037e20; gMinimapTilesGfx = .;
. = 0x00038000; gSram = .;

View File

@ -693,66 +693,66 @@ u8 BgClipCheckOpeningHatch(u16 xPosition, u16 yPosition)
for (i = 0; i < MAX_AMOUNT_OF_HATCHES; i++)
{
if (gHatchData[i].exists && !gHatchData[i].opening)
if (!gHatchData[i].exists || gHatchData[i].state != HATCH_STATE_CLOSED)
continue;
action = HATCH_OPENING_ACTION_NOT_OPENING;
// Check touches hatch and hatch is weak
if (gHatchData[i].xPosition == xPosition && gHatchData[i].yPosition <= yPosition &&
yPosition <= gHatchData[i].yPosition + (HATCH_VERTICAL_SIZE - 1) &&
sHatchBehaviors[gHatchData[i].type][0] &
sClipdataAffectingActionDamageTypes[gCurrentClipdataAffectingAction])
{
action = HATCH_OPENING_ACTION_NOT_OPENING;
// Increase hits
gHatchData[i].hits++;
action = HATCH_OPENING_ACTION_OPENING;
// Check touches hatch and hatch is weak
if (gHatchData[i].xPosition == xPosition && gHatchData[i].yPosition <= yPosition &&
yPosition <= gHatchData[i].yPosition + (HATCH_VERTICAL_SIZE - 1) &&
sHatchBehaviors[gHatchData[i].type][0] &
sClipdataAffectingActionDamageTypes[gCurrentClipdataAffectingAction])
// Check for a special action
if (gHatchData[i].type == HATCH_LOCKED)
{
// Increase hits
gHatchData[i].hits++;
action = HATCH_OPENING_ACTION_OPENING;
// Check for a special action
if (gHatchData[i].type == HATCH_LOCKED)
{
// Check hatches are unlocked
if (!gHatchesState.unlocking)
action = HATCH_OPENING_ACTION_LOCKED;
}
else if (gHatchData[i].type == HATCH_LOCKED_AND_LOCK_DESTINATION)
{
if (!gHatchesState.unk)
action = HATCH_OPENING_ACTION_LOCKED;
}
else if (gHatchData[i].type == HATCH_MISSILE)
{
// Check instantly open
if (sClipdataAffectingActionDamageTypes[gCurrentClipdataAffectingAction] & CAA_DAMAGE_TYPE_SUPER_MISSILE)
gHatchData[i].hits = sHatchBehaviors[HATCH_MISSILE][1]; // Set max health
}
// Check hatches are unlocked
if (!gHatchesState.unlocking)
action = HATCH_OPENING_ACTION_LOCKED;
}
if (action != HATCH_OPENING_ACTION_NOT_OPENING)
else if (gHatchData[i].type == HATCH_LOCKED_NAVIGATION)
{
if (action == HATCH_OPENING_ACTION_OPENING)
if (!gHatchesState.navigationDoorsUnlocking)
action = HATCH_OPENING_ACTION_LOCKED;
}
else if (gHatchData[i].type == HATCH_MISSILE)
{
// Check instantly open
if (sClipdataAffectingActionDamageTypes[gCurrentClipdataAffectingAction] & CAA_DAMAGE_TYPE_SUPER_MISSILE)
gHatchData[i].hits = sHatchBehaviors[HATCH_MISSILE][1]; // Set max health
}
}
if (action != HATCH_OPENING_ACTION_NOT_OPENING)
{
if (action == HATCH_OPENING_ACTION_OPENING)
{
// Check enough hits
if (gHatchData[i].hits >= sHatchBehaviors[gHatchData[i].type][1])
{
// Check enough hits
if (gHatchData[i].hits >= sHatchBehaviors[gHatchData[i].type][1])
{
// Unlock
gHatchData[i].flashingTimer = FALSE;
gHatchData[i].opening = TRUE;
// Unlock
gHatchData[i].flashingTimer = FALSE;
gHatchData[i].state = TRUE;
// Set hatch as opened
if (gHatchData[i].type >= HATCH_MISSILE)
ConnectionSetHatchAsOpened(HATCH_ACTION_SETTING_SOURCE_AND_DESTINATION, gHatchData[i].sourceDoor);
else
ConnectionSetHatchAsOpened(HATCH_ACTION_SETTING_SOURCE, gHatchData[i].sourceDoor);
}
// Set hatch as opened
if (gHatchData[i].type >= HATCH_MISSILE)
ConnectionSetHatchAsOpened(HATCH_ACTION_SETTING_SOURCE_AND_DESTINATION, gHatchData[i].sourceDoor);
else
gHatchData[i].flashingTimer = 1; // Set flashing
ConnectionSetHatchAsOpened(HATCH_ACTION_SETTING_SOURCE, gHatchData[i].sourceDoor);
}
else
gHatchData[i].hits = 0; // Locked, reset
gHatchData[i].hitTimer = 0;
break;
gHatchData[i].flashingTimer = 1; // Set flashing
}
else
gHatchData[i].hits = 0; // Locked, reset
gHatchData[i].hitTimer = 0;
break;
}
}

View File

@ -41,72 +41,79 @@ void ConnectionUpdateHatches(void)
{
if (!gHatchData[i].exists)
continue;
if (gHatchData[i].opening != TRUE && gHatchData[i].opening != 0x3)
// Check to update flashing hatches
if (gHatchData[i].state != HATCH_STATE_OPENING && gHatchData[i].state != HATCH_STATE_CLOSING)
{
if (gHatchData[i].flashingTimer != 0x0 && gHatchData[i].type == HATCH_MISSILE)
if (gHatchData[i].flashingTimer != 0 && gHatchData[i].type == HATCH_MISSILE)
ConnectionHatchFlashingAnimation(i);
continue;
}
else
if (gHatchData[i].currentAnimationFrame == 0)
{
if (gHatchData[i].currentAnimationFrame == 0x0)
// Check play hatch opening/closing sound
if (gHatchData[i].state == HATCH_STATE_OPENING)
{
if (gHatchData[i].opening == TRUE)
{
SoundPlay(SOUND_DOOR_OPENING);
}
else
{
switch (gHatchData[i].type)
{
case HATCH_LOCKED:
case HATCH_LOCKED_AND_LOCK_DESTINATION:
SoundPlay(SOUND_DOORS_LOCKING);
break;
case HATCH_NONE:
case HATCH_SUPER_MISSILE:
case HATCH_POWER_BOMB:
default:
SoundPlay(SOUND_DOOR_CLOSING);
break;
}
}
gHatchData[i].animationDurationCounter = 0x0;
gHatchData[i].currentAnimationFrame++;
}
else if (gHatchData[i].currentAnimationFrame == 0x7)
{
if (gHatchData[i].opening == TRUE)
{
gHatchData[i].currentAnimationFrame = 0x4;
ConnectionUpdateHatchAnimation(TRUE, i);
gHatchData[i].opening = 0x2;
gHatchData[i].currentAnimationFrame = 0x0;
}
SoundPlay(SOUND_DOOR_OPENING);
}
else
{
if (gHatchData[i].animationDurationCounter < sHatchesAnimationDurationCounter[gHatchData[i].currentAnimationFrame])
gHatchData[i].animationDurationCounter++;
else
switch (gHatchData[i].type)
{
gHatchData[i].animationDurationCounter = 0x0;
ConnectionUpdateHatchAnimation(TRUE, i);
gHatchData[i].currentAnimationFrame++;
if (gHatchData[i].currentAnimationFrame == 0x5)
{
if (gHatchData[i].opening == TRUE)
gHatchData[i].opening = 0x2;
else if (gHatchData[i].opening == 0x3)
gHatchData[i].opening = 0x0;
gHatchData[i].currentAnimationFrame = 0x0;
}
case HATCH_LOCKED:
case HATCH_LOCKED_NAVIGATION:
// Locked door type
SoundPlay(SOUND_DOORS_LOCKING);
break;
case HATCH_NONE:
case HATCH_SUPER_MISSILE:
case HATCH_POWER_BOMB:
default:
// Any other door type is considered unlocked
SoundPlay(SOUND_DOOR_CLOSING);
break;
}
}
// Advance to next animation frame
gHatchData[i].animationDurationCounter = 0;
gHatchData[i].currentAnimationFrame++;
}
else if (gHatchData[i].currentAnimationFrame == 7)
{
if (gHatchData[i].state == HATCH_STATE_OPENING)
{
gHatchData[i].currentAnimationFrame = 0x4;
ConnectionUpdateHatchAnimation(TRUE, i);
gHatchData[i].state = HATCH_STATE_OPENED;
gHatchData[i].currentAnimationFrame = 0;
}
}
else
{
// Check update animation counter
if (gHatchData[i].animationDurationCounter < sHatchesAnimationDurationCounter[gHatchData[i].currentAnimationFrame])
{
APPLY_DELTA_TIME_INC(gHatchData[i].animationDurationCounter);
continue;
}
gHatchData[i].animationDurationCounter = 0;
ConnectionUpdateHatchAnimation(TRUE, i);
gHatchData[i].currentAnimationFrame++;
if (gHatchData[i].currentAnimationFrame == 5)
{
if (gHatchData[i].state == HATCH_STATE_OPENING)
gHatchData[i].state = HATCH_STATE_OPENED;
else if (gHatchData[i].state == HATCH_STATE_CLOSING)
gHatchData[i].state = HATCH_STATE_CLOSED;
gHatchData[i].currentAnimationFrame = 0;
}
}
}
}
@ -126,7 +133,7 @@ void ConnectionUpdateHatchAnimation(u8 dontSetRaw, u32 hatchNbr)
caf = gHatchData[hatchNbr].currentAnimationFrame - 1;
if (gHatchData[hatchNbr].opening == 3)
if (gHatchData[hatchNbr].state == HATCH_STATE_CLOSING)
{
caf = 2 - caf;
if (caf < 0)
@ -136,34 +143,34 @@ void ConnectionUpdateHatchAnimation(u8 dontSetRaw, u32 hatchNbr)
}
else
{
if (gHatchData[hatchNbr].type != 0)
if (gHatchData[hatchNbr].type != HATCH_NONE)
caf += 0x40;
}
}
if (gHatchData[hatchNbr].type == 0)
if (gHatchData[hatchNbr].type == HATCH_NONE)
caf += 0x80;
tilemapValue += caf;
if (dontSetRaw)
{
BgClipSetBg1BlockValue(tilemapValue, gHatchData[hatchNbr].yPosition, gHatchData[hatchNbr].xPosition);
BgClipSetBg1BlockValue(tilemapValue + 0x10, gHatchData[hatchNbr].yPosition + 1, gHatchData[hatchNbr].xPosition);
BgClipSetBg1BlockValue(tilemapValue + 0x20, gHatchData[hatchNbr].yPosition + 2, gHatchData[hatchNbr].xPosition);
BgClipSetBg1BlockValue(tilemapValue + 0x30, gHatchData[hatchNbr].yPosition + 3, gHatchData[hatchNbr].xPosition);
BgClipSetBg1BlockValue(tilemapValue + 16 * 0, gHatchData[hatchNbr].yPosition + 0, gHatchData[hatchNbr].xPosition);
BgClipSetBg1BlockValue(tilemapValue + 16 * 1, gHatchData[hatchNbr].yPosition + 1, gHatchData[hatchNbr].xPosition);
BgClipSetBg1BlockValue(tilemapValue + 16 * 2, gHatchData[hatchNbr].yPosition + 2, gHatchData[hatchNbr].xPosition);
BgClipSetBg1BlockValue(tilemapValue + 16 * 3, gHatchData[hatchNbr].yPosition + 3, gHatchData[hatchNbr].xPosition);
}
else
{
BgClipSetRawBG1BlockValue(tilemapValue, gHatchData[hatchNbr].yPosition, gHatchData[hatchNbr].xPosition);
BgClipSetRawBG1BlockValue(tilemapValue + 0x10, gHatchData[hatchNbr].yPosition + 1, gHatchData[hatchNbr].xPosition);
BgClipSetRawBG1BlockValue(tilemapValue + 0x20, gHatchData[hatchNbr].yPosition + 2, gHatchData[hatchNbr].xPosition);
BgClipSetRawBG1BlockValue(tilemapValue + 0x30, gHatchData[hatchNbr].yPosition + 3, gHatchData[hatchNbr].xPosition);
BgClipSetRawBG1BlockValue(tilemapValue + 16 * 0, gHatchData[hatchNbr].yPosition + 0, gHatchData[hatchNbr].xPosition);
BgClipSetRawBG1BlockValue(tilemapValue + 16 * 1, gHatchData[hatchNbr].yPosition + 1, gHatchData[hatchNbr].xPosition);
BgClipSetRawBG1BlockValue(tilemapValue + 16 * 2, gHatchData[hatchNbr].yPosition + 2, gHatchData[hatchNbr].xPosition);
BgClipSetRawBG1BlockValue(tilemapValue + 16 * 3, gHatchData[hatchNbr].yPosition + 3, gHatchData[hatchNbr].xPosition);
}
BgClipSetClipdataBlockValue(tilemapValue, gHatchData[hatchNbr].yPosition, gHatchData[hatchNbr].xPosition);
BgClipSetClipdataBlockValue(tilemapValue + 0x10, gHatchData[hatchNbr].yPosition + 1, gHatchData[hatchNbr].xPosition);
BgClipSetClipdataBlockValue(tilemapValue + 0x20, gHatchData[hatchNbr].yPosition + 2, gHatchData[hatchNbr].xPosition);
BgClipSetClipdataBlockValue(tilemapValue + 0x30, gHatchData[hatchNbr].yPosition + 3, gHatchData[hatchNbr].xPosition);
BgClipSetClipdataBlockValue(tilemapValue + 16 * 0, gHatchData[hatchNbr].yPosition + 0, gHatchData[hatchNbr].xPosition);
BgClipSetClipdataBlockValue(tilemapValue + 16 * 1, gHatchData[hatchNbr].yPosition + 1, gHatchData[hatchNbr].xPosition);
BgClipSetClipdataBlockValue(tilemapValue + 16 * 2, gHatchData[hatchNbr].yPosition + 2, gHatchData[hatchNbr].xPosition);
BgClipSetClipdataBlockValue(tilemapValue + 16 * 3, gHatchData[hatchNbr].yPosition + 3, gHatchData[hatchNbr].xPosition);
}
/**
@ -177,14 +184,17 @@ void ConnectionHatchFlashingAnimation(u8 hatch)
// Update hit timer
if (gHatchData[hatch].hitTimer == 0)
gHatchData[hatch].hitTimer = 4;
{
gHatchData[hatch].hitTimer = CONVERT_SECONDS(1.f / 15);
}
else
{
gHatchData[hatch].hitTimer--;
APPLY_DELTA_TIME_DEC(gHatchData[hatch].hitTimer);
return;
}
if (gHatchData[hatch].flashingTimer & 1)
// Alternate between the flashing hatch graphics and the normal hatch graphics
if (MOD_AND(gHatchData[hatch].flashingTimer, CONVERT_SECONDS(1.f / 30)))
value = CLIPDATA_TILEMAP_FLAG | CLIPDATA_TILEMAP_NO_HATCH_DOOR_TOP_LEFT; // Flashing door cap
else
value = sHatchesTilemapValues[gHatchData[hatch].type];
@ -192,17 +202,17 @@ void ConnectionHatchFlashingAnimation(u8 hatch)
if (gHatchData[hatch].facingRight)
value++;
// Update Gfx
BgClipSetBg1BlockValue(value, gHatchData[hatch].yPosition, gHatchData[hatch].xPosition);
BgClipSetBg1BlockValue(value + 0x10, gHatchData[hatch].yPosition + 1, gHatchData[hatch].xPosition);
BgClipSetBg1BlockValue(value + 0x20, gHatchData[hatch].yPosition + 2, gHatchData[hatch].xPosition);
BgClipSetBg1BlockValue(value + 0x30, gHatchData[hatch].yPosition + 3, gHatchData[hatch].xPosition);
// Update gfx
BgClipSetBg1BlockValue(value + 16 * 0, gHatchData[hatch].yPosition + 0, gHatchData[hatch].xPosition);
BgClipSetBg1BlockValue(value + 16 * 1, gHatchData[hatch].yPosition + 1, gHatchData[hatch].xPosition);
BgClipSetBg1BlockValue(value + 16 * 2, gHatchData[hatch].yPosition + 2, gHatchData[hatch].xPosition);
BgClipSetBg1BlockValue(value + 16 * 3, gHatchData[hatch].yPosition + 3, gHatchData[hatch].xPosition);
// Update timer
if (gHatchData[hatch].flashingTimer >= 4)
if (gHatchData[hatch].flashingTimer >= CONVERT_SECONDS(1.f / 15))
gHatchData[hatch].flashingTimer = 0;
else
gHatchData[hatch].flashingTimer++;
APPLY_DELTA_TIME_INC(gHatchData[hatch].flashingTimer);
}
/**
@ -221,22 +231,23 @@ void ConnectionOverrideOpenedHatch(u8 hatch, u32 type)
// Change type
gHatchData[hatch].type = type;
// Change hatch behavior
// Update hatch gfx
value = sHatchesTilemapValues[gHatchData[hatch].type] + gHatchData[hatch].facingRight;
BgClipSetBg1BlockValue(value, gHatchData[hatch].yPosition, gHatchData[hatch].xPosition);
BgClipSetBg1BlockValue(value + 0x10, gHatchData[hatch].yPosition + 0x1, gHatchData[hatch].xPosition);
BgClipSetBg1BlockValue(value + 0x20, gHatchData[hatch].yPosition + 0x2, gHatchData[hatch].xPosition);
BgClipSetBg1BlockValue(value + 0x30, gHatchData[hatch].yPosition + 0x3, gHatchData[hatch].xPosition);
BgClipSetBg1BlockValue(value + 16 * 0, gHatchData[hatch].yPosition + 0, gHatchData[hatch].xPosition);
BgClipSetBg1BlockValue(value + 16 * 1, gHatchData[hatch].yPosition + 1, gHatchData[hatch].xPosition);
BgClipSetBg1BlockValue(value + 16 * 2, gHatchData[hatch].yPosition + 2, gHatchData[hatch].xPosition);
BgClipSetBg1BlockValue(value + 16 * 3, gHatchData[hatch].yPosition + 3, gHatchData[hatch].xPosition);
BgClipSetClipdataBlockValue(value, gHatchData[hatch].yPosition, gHatchData[hatch].xPosition);
BgClipSetClipdataBlockValue(value + 0x10, gHatchData[hatch].yPosition + 0x1, gHatchData[hatch].xPosition);
BgClipSetClipdataBlockValue(value + 0x20, gHatchData[hatch].yPosition + 0x2, gHatchData[hatch].xPosition);
BgClipSetClipdataBlockValue(value + 0x30, gHatchData[hatch].yPosition + 0x3, gHatchData[hatch].xPosition);
BgClipSetClipdataBlockValue(value + 16 * 0, gHatchData[hatch].yPosition + 0, gHatchData[hatch].xPosition);
BgClipSetClipdataBlockValue(value + 16 * 1, gHatchData[hatch].yPosition + 1, gHatchData[hatch].xPosition);
BgClipSetClipdataBlockValue(value + 16 * 2, gHatchData[hatch].yPosition + 2, gHatchData[hatch].xPosition);
BgClipSetClipdataBlockValue(value + 16 * 3, gHatchData[hatch].yPosition + 3, gHatchData[hatch].xPosition);
gHatchData[hatch].opening = FALSE;
gHatchData[hatch].currentAnimationFrame = 0x0;
gHatchData[hatch].animationDurationCounter = 0x0;
// Force closed
gHatchData[hatch].state = HATCH_STATE_CLOSED;
gHatchData[hatch].currentAnimationFrame = 0;
gHatchData[hatch].animationDurationCounter = 0;
}
/**
@ -252,7 +263,9 @@ u32 ConnectionCheckEnterDoor(u16 yPosition, u16 xPosition)
struct HatchData* pHatch;
s32 i;
u8 state;
u8 doorType;
// Don't care for doors if not in control of samus
if (gGameModeSub1 != SUB_GAME_MODE_PLAYING)
return FALSE;
@ -261,48 +274,85 @@ u32 ConnectionCheckEnterDoor(u16 yPosition, u16 xPosition)
for (i = 0; i < MAX_AMOUNT_OF_HATCHES; i++)
{
if (gHatchData[i].sourceDoor != sHatchData_Empty.sourceDoor)
// Ignore doors that don't exist
if (gHatchData[i].sourceDoor == sHatchData_Empty.sourceDoor)
continue;
pDoor = sAreaDoorsPointers[gCurrentArea] + gHatchData[i].sourceDoor;
doorType = pDoor->type & DOOR_TYPE_NO_FLAGS;
// Ignore doors that are invalid and area connections
if (doorType == DOOR_TYPE_NONE || doorType == DOOR_TYPE_AREA_CONNECTION)
continue;
// Check within the door
if (pDoor->xStart <= xPosition && xPosition <= pDoor->xEnd &&
pDoor->yStart <= yPosition && yPosition <= pDoor->yEnd)
{
pDoor = sAreaDoorsPointers[gCurrentArea] + gHatchData[i].sourceDoor;
gDoorPositionStart.x = 0;
gDoorPositionStart.y = 0;
if ((pDoor->type & DOOR_TYPE_NO_FLAGS) > DOOR_TYPE_AREA_CONNECTION && pDoor->xStart <= xPosition &&
xPosition <= pDoor->xEnd && pDoor->yStart <= yPosition && yPosition <= pDoor->yEnd)
if (pDoor->type & DOOR_TYPE_LOAD_EVENT_BASED_ROOM)
{
gDoorPositionStart.x = 0;
gDoorPositionStart.y = 0;
if (pDoor->type & DOOR_TYPE_LOAD_EVENT_BASED_ROOM)
// Check for an event based connection
state = ConnectionFindEventBasedDoor(gHatchData[i].sourceDoor);
if (state != UCHAR_MAX)
{
state = ConnectionFindEventBasedDoor(gHatchData[i].sourceDoor);
if (state != 0xFF)
gLastDoorUsed = state;
else
gLastDoorUsed = pDoor->destinationDoor;
// An event based connection was found, override the original connection
gLastDoorUsed = state;
}
else
gLastDoorUsed = pDoor->destinationDoor;
if ((pDoor->type & DOOR_TYPE_NO_FLAGS) > DOOR_TYPE_NO_HATCH)
{
if (pDoor->xStart > (gBg1XPosition >> 0x6) + 8)
gDoorPositionStart.x = 1;
gDoorPositionStart.y = pDoor->yStart;
// No event based connection found, keep the normal destination
gLastDoorUsed = pDoor->destinationDoor;
}
}
else
{
// No need to check for anything, simply use the normal destination
gLastDoorUsed = pDoor->destinationDoor;
}
doorType = pDoor->type & DOOR_TYPE_NO_FLAGS;
// First two checks are redundant
// The last check decides if a door transition should happen
if (doorType != DOOR_TYPE_NONE && doorType != DOOR_TYPE_AREA_CONNECTION && doorType != DOOR_TYPE_NO_HATCH)
{
if (pDoor->xStart > SUB_PIXEL_TO_BLOCK(gBg1XPosition) + CEIL(SCREEN_SIZE_X_BLOCKS / 2))
{
// Mark that the transition should happen from a door to the right, since the default is from the left
gDoorPositionStart.x = 1;
}
gSamusDoorPositionOffset = (pDoor->yEnd + 1) * BLOCK_SIZE - gSamusData.yPosition - 1;
ConnectionProcessDoorType(pDoor->type);
gGameModeSub1 = SUB_GAME_MODE_LOADING_ROOM;
if (gHatchData[i].exists && gHatchData[i].opening == TRUE)
gHatchData[i].currentAnimationFrame = 7;
pDoor = sAreaDoorsPointers[gCurrentArea] + gLastDoorUsed;
ConnectionCheckPlayCutsceneDuringTransition(gCurrentArea, pDoor->sourceRoom + 1);
CheckPlayRoomMusicTrack(gCurrentArea, pDoor->sourceRoom);
state = TRUE;
break;
gDoorPositionStart.y = pDoor->yStart;
}
// Compute the vertical offset of Samus within the door
// Start from the bottom of the door (+ 1 to align to the bottom of the door)
// Then remove samus' position
gSamusDoorPositionOffset = BLOCK_TO_SUB_PIXEL(pDoor->yEnd + 1) - gSamusData.yPosition - 1;
ConnectionProcessDoorType(pDoor->type);
// Start the room loading behavior
gGameModeSub1 = SUB_GAME_MODE_LOADING_ROOM;
if (gHatchData[i].exists && gHatchData[i].state == HATCH_STATE_OPENING)
{
// Cut the animation to the end if the hatch is still opening
gHatchData[i].currentAnimationFrame = 7;
}
// Check for stuff during the transition
pDoor = sAreaDoorsPointers[gCurrentArea] + gLastDoorUsed;
// Check for cutscenes
ConnectionCheckPlayCutsceneDuringTransition(gCurrentArea, pDoor->sourceRoom + 1);
// Check for music
CheckPlayRoomMusicTrack(gCurrentArea, pDoor->sourceRoom);
state = TRUE;
break;
}
}
@ -323,6 +373,7 @@ u32 ConnectionCheckAreaConnection(u16 yPosition, u16 xPosition)
s32 i;
s32 j;
u8 state;
u8 doorType;
if (gGameModeSub1 != SUB_GAME_MODE_PLAYING)
return FALSE;
@ -332,63 +383,96 @@ u32 ConnectionCheckAreaConnection(u16 yPosition, u16 xPosition)
for (i = 0; i < MAX_AMOUNT_OF_HATCHES; i++)
{
if (gHatchData[i].sourceDoor != sHatchData_Empty.sourceDoor)
{
pDoor = sAreaDoorsPointers[gCurrentArea] + gHatchData[i].sourceDoor;
// Ignore doors that don't exist
if (gHatchData[i].sourceDoor == sHatchData_Empty.sourceDoor)
continue;
if ((pDoor->type & DOOR_TYPE_NO_FLAGS) == DOOR_TYPE_AREA_CONNECTION && pDoor->xStart <= xPosition &&
xPosition <= pDoor->xEnd && pDoor->yStart <= yPosition && yPosition <= pDoor->yEnd)
pDoor = sAreaDoorsPointers[gCurrentArea] + gHatchData[i].sourceDoor;
doorType = pDoor->type & DOOR_TYPE_NO_FLAGS;
// Ignore doors that aren't area connections
if (doorType != DOOR_TYPE_AREA_CONNECTION)
continue;
// Check within the door
if (pDoor->xStart <= xPosition && xPosition <= pDoor->xEnd &&
pDoor->yStart <= yPosition && yPosition <= pDoor->yEnd)
{
if (pDoor->type & DOOR_TYPE_LOAD_EVENT_BASED_ROOM)
{
if (pDoor->type & DOOR_TYPE_LOAD_EVENT_BASED_ROOM)
// Check for an event based connection
state = ConnectionFindEventBasedDoor(gHatchData[i].sourceDoor);
if (state != UCHAR_MAX)
{
state = ConnectionFindEventBasedDoor(gHatchData[i].sourceDoor);
if (state != 0xFF)
gLastDoorUsed = state;
else
gLastDoorUsed = pDoor->destinationDoor;
// An event based connection was found, override the original connection
gLastDoorUsed = state;
}
else
{
// No event based connection found, keep the normal destination
gLastDoorUsed = pDoor->destinationDoor;
state = 0x1;
break;
}
}
else
{
// No need to check for anything, simply use the normal destination
gLastDoorUsed = pDoor->destinationDoor;
}
state = TRUE;
break;
}
}
if (!state)
return FALSE;
j = 0;
while (sAreaConnections[j][0] != AREA_NONE)
{
if (sAreaConnections[j][0] == gCurrentArea && sAreaConnections[j][1] == gHatchData[i].sourceDoor)
// No door was found, abort
return FALSE;
}
// Try to look for the corresponding area connection
j = 0;
while (sAreaConnections[j][AREA_CONNECTION_FIELD_SOURCE_AREA] != AREA_NONE)
{
if (sAreaConnections[j][AREA_CONNECTION_FIELD_SOURCE_AREA] == gCurrentArea &&
sAreaConnections[j][AREA_CONNECTION_FIELD_SOURCE_DOOR] == gHatchData[i].sourceDoor)
{
gCurrentArea = sAreaConnections[j][2];
state = 0x2;
gCurrentArea = sAreaConnections[j][AREA_CONNECTION_FIELD_DESTINATION_AREA];
state = 2;
break;
}
j++;
}
if (state != 0x2)
if (state != 2)
{
gLastDoorUsed = 0x0;
// No area connection was found
gLastDoorUsed = 0;
return FALSE;
}
if (gSamusData.pose == SPOSE_USING_AN_ELEVATOR)
gSamusDoorPositionOffset = 0x0;
{
// No vertical offset when using an elevator, since they are horizontal
gSamusDoorPositionOffset = 0;
}
else
gSamusDoorPositionOffset = (pDoor->yEnd + 0x1) * BLOCK_SIZE - gSamusData.yPosition - 0x1;
{
// Compute vertical offset as normal
gSamusDoorPositionOffset = BLOCK_TO_SUB_PIXEL(pDoor->yEnd + 1) - gSamusData.yPosition - 1;
}
ColorFadingStart(0x6); // No transition
ColorFadingStart(COLOR_FADING_NO_TRANSITION);
gGameModeSub1 = SUB_GAME_MODE_LOADING_ROOM;
pDoor = sAreaDoorsPointers[gCurrentArea] + gLastDoorUsed;
ConnectionCheckPlayCutsceneDuringElevator();
// Check for stuff during the transition
pDoor = sAreaDoorsPointers[gCurrentArea] + gLastDoorUsed;
// Check for cutscenes
ConnectionCheckPlayCutsceneDuringAreaConnection();
// Check for music
CheckPlayRoomMusicTrack(gCurrentArea, pDoor->sourceRoom);
return TRUE;
}
@ -414,6 +498,7 @@ void ConnectionProcessDoorType(u8 type)
break;
default:
// Use door transition coordinates instead of background coordinates
gWhichBGPositionIsWrittenToBG3OFS = 4;
if (!gSkipDoorTransition)
transition = COLOR_FADING_DOOR_TRANSITION;
@ -435,17 +520,21 @@ void ConnectionProcessDoorType(u8 type)
u8 ConnectionFindEventBasedDoor(u8 sourceDoor)
{
s32 i;
for (i = MAX_AMOUNT_OF_EVENT_BASED_CONNECTIONS - 1; i >= 0; i--)
// Looping backwards to prioritze the latter events?
for (i = ARRAY_SIZE(sEventBasedConnections) - 1; i >= 0; i--)
{
if (gCurrentArea != sEventBasedConnections[i][0])
continue;
if (sourceDoor != sEventBasedConnections[i][1])
// Check correct area
if (gCurrentArea != sEventBasedConnections[i][EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA])
continue;
if (EventFunction(EVENT_ACTION_CHECKING, sEventBasedConnections[i][2]))
return sEventBasedConnections[i][3];
// Check correct door
if (sourceDoor != sEventBasedConnections[i][EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR])
continue;
// Check event
if (EventFunction(EVENT_ACTION_CHECKING, sEventBasedConnections[i][EVENT_BASED_CONNECTION_FIELD_EVENT]))
return sEventBasedConnections[i][EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR];
}
return UCHAR_MAX;
@ -466,8 +555,7 @@ u32 ConnectionSetHatchAsOpened(u8 action, u8 hatch)
u32 chunk;
struct Door currDoor;
// 0x2037c00 = gHatchesOpened
pHatch = (u32*)(0x2037c00 + gCurrentArea * 32);
pHatch = gHatchesOpened[gCurrentArea];
closed = FALSE;
// Get chunk and bit
@ -512,16 +600,19 @@ u32 ConnectionSetHatchAsOpened(u8 action, u8 hatch)
*/
void ConnectionCheckUnlockDoors(void)
{
if (gDoorUnlockTimer < 0x0)
if (gDoorUnlockTimer >= 0)
{
// Update timer
gDoorUnlockTimer++;
if (gDoorUnlockTimer == 0x0 && (gHatchesState.hatchesLockedWithTimer || gHatchesState.unk2))
{
// Timer done and has hatches to unlock
SoundPlay(SOUND_DOORS_UNLOCKING);
gHatchesState.unlocking = TRUE;
}
// The door unlock timer isn't active, no need to do anything
return;
}
// Update timer
APPLY_DELTA_TIME_INC(gDoorUnlockTimer);
if (gDoorUnlockTimer == 0 && (gHatchesState.hatchesLockedWithTimer || gHatchesState.hatchesLockedWithEventUnlockeable))
{
// Timer done and has hatches to unlock
SoundPlay(SOUND_DOORS_UNLOCKING);
gHatchesState.unlocking = TRUE;
}
}
@ -530,11 +621,11 @@ void ConnectionCheckUnlockDoors(void)
*
* @param dontSetRaw Don't set raw flag
* @param hatch Hatch ID
* @param status Opening status
* @param state Opening status
*/
void ConnectionHatchStartLockAnimation(u8 dontSetRaw, u8 hatch, u8 status)
void ConnectionHatchStartLockAnimation(u8 dontSetRaw, u8 hatch, u8 state)
{
gHatchData[hatch].opening = status;
gHatchData[hatch].state = state;
gHatchData[hatch].currentAnimationFrame = 0;
ConnectionUpdateHatchAnimation(dontSetRaw, hatch);
@ -550,68 +641,76 @@ void ConnectionLockHatches(u8 isEvent)
s32 i;
u16 lockedHatches;
s32 hatch;
i = 0;
lockedHatches = 0;
for (; i < MAX_AMOUNT_OF_HATCHES; i++)
// Create bit mask for the hatches in the current room
for (i = 0, lockedHatches = 0; i < MAX_AMOUNT_OF_HATCHES; i++)
{
if (gHatchData[i].exists)
lockedHatches |= (1 << i);
}
// Mask to only keep the hatches that actually exist
if (!isEvent)
{
gHatchesState.hatchesLockedWithTimer &= lockedHatches;
}
else
{
gHatchesState.hatchesLockedWithEvent &= lockedHatches;
gHatchesState.unk2 &= lockedHatches;
gHatchesState.hatchesLockedWithEventUnlockeable &= lockedHatches;
}
if (!isEvent)
{
lockedHatches = gHatchesState.hatchesLockedWithTimer &= ~(gHatchesState.hatchesLockedWithEvent | gHatchesState.unk2);
// Remove hatches that were locked via an event, at this point only the normal, non locked hatches will be processed
lockedHatches = gHatchesState.hatchesLockedWithTimer &= ~(gHatchesState.hatchesLockedWithEvent | gHatchesState.hatchesLockedWithEventUnlockeable);
i = 0;
hatch = 0;
for (; i < MAX_AMOUNT_OF_HATCHES; i++)
for (i = 0, hatch = 0; i < MAX_AMOUNT_OF_HATCHES; hatch++, i++)
{
// Verify if the hatch should be locked
if ((lockedHatches >> i) & 1)
{
gHatchData[i].locked = TRUE;
// Lock the hatch
gHatchData[i].locked = HATCH_LOCK_STATE_LOCKED;
gHatchData[i].type = HATCH_LOCKED;
// Set closed, or closing if it's the hatch we're coming from
if (gHatchData[i].sourceDoor != gLastDoorUsed)
ConnectionHatchStartLockAnimation(TRUE, hatch, FALSE);
ConnectionHatchStartLockAnimation(TRUE, hatch, HATCH_STATE_CLOSED);
else
ConnectionHatchStartLockAnimation(TRUE, hatch, 3);
ConnectionHatchStartLockAnimation(TRUE, hatch, HATCH_STATE_CLOSING);
}
hatch++;
}
}
else
{
lockedHatches = gHatchesState.hatchesLockedWithEvent | gHatchesState.unk2;
// Include both types of locked doors
lockedHatches = gHatchesState.hatchesLockedWithEvent | gHatchesState.hatchesLockedWithEventUnlockeable;
for (i = 0, hatch = 0; i < MAX_AMOUNT_OF_HATCHES; hatch++, i++)
{
// Verify if the hatch should be locked
if ((lockedHatches >> i) & 1)
{
if ((gHatchesState.unk2 >> i) & 1)
// Can be 2 different types of locked
if ((gHatchesState.hatchesLockedWithEventUnlockeable >> i) & 1)
{
gHatchData[hatch].locked = TRUE;
// Normal locked, can be opened with the door unlock timer
gHatchData[hatch].locked = HATCH_LOCK_STATE_LOCKED;
gHatchData[hatch].type = HATCH_LOCKED;
}
else
{
gHatchData[hatch].locked = 2;
gHatchData[hatch].type = HATCH_LOCKED_AND_LOCK_DESTINATION;
// Fully locked, with no way to be opened
gHatchData[hatch].locked = HATCH_LOCK_STATE_PERMA_LOCKED;
gHatchData[hatch].type = HATCH_LOCKED_NAVIGATION;
}
// Set closed, or closing if it's the hatch we're coming from
if (gHatchData[hatch].sourceDoor != gLastDoorUsed)
ConnectionHatchStartLockAnimation(TRUE, hatch, FALSE);
ConnectionHatchStartLockAnimation(TRUE, hatch, HATCH_STATE_CLOSED);
else
ConnectionHatchStartLockAnimation(TRUE, hatch, 3);
ConnectionHatchStartLockAnimation(TRUE, hatch, HATCH_STATE_CLOSING);
}
}
}
@ -701,14 +800,14 @@ void ConnectionLoadDoors(void)
i = gNumberOfValidHatchesInRoom;
if (i < MAX_AMOUNT_OF_HATCHES)
{
// Actually the the first hatch doesn't exist
// Try to find the first hatch that doesn't exist
for (; i < MAX_AMOUNT_OF_HATCHES; i++)
{
if (!gHatchData[i].exists)
break;
}
// Check again, just in case
// Check if a valid hatch was found
if (i < MAX_AMOUNT_OF_HATCHES)
{
// Set type
@ -736,7 +835,7 @@ void ConnectionLoadDoors(void)
// Set hatch lock flag
if (hatchType == HATCH_LOCKED)
gHatchesState.hatchesLockedWithTimer |= (1 << i);
else if (hatchType == HATCH_LOCKED_AND_LOCK_DESTINATION)
else if (hatchType == HATCH_LOCKED_NAVIGATION)
gHatchesState.hatchesLockedWithEvent |= (1 << i);
}
else
@ -794,8 +893,12 @@ void ConnectionLoadDoors(void)
if (!gHatchData[i].exists)
continue;
// Is a hatch, and has been opened
if (gHatchData[i].type > HATCH_UNUSED && !ConnectionSetHatchAsOpened(HATCH_ACTION_CHECKING_OPENED, gHatchData[i].sourceDoor))
// Is a hatch
if (gHatchData[i].type == HATCH_NONE || gHatchData[i].type == HATCH_UNUSED)
continue;
// And has been opened
if (!ConnectionSetHatchAsOpened(HATCH_ACTION_CHECKING_OPENED, gHatchData[i].sourceDoor))
ConnectionOverrideOpenedHatch(i, HATCH_NORMAL);
}
@ -803,7 +906,7 @@ void ConnectionLoadDoors(void)
{
// Check start lock animation
if (gHatchData[currHatchId].exists && gHatchData[currHatchId].type != HATCH_NONE)
ConnectionHatchStartLockAnimation(FALSE, currHatchId, 3);
ConnectionHatchStartLockAnimation(FALSE, currHatchId, HATCH_STATE_CLOSING);
// Get X position
currDoor = gHatchData[currHatchId].xPosition;
@ -829,7 +932,7 @@ void ConnectionLoadDoors(void)
gIoRegistersBackup.BLDALPHA_NonGameplay_EVB = gBldalphaData1.evbCoef;
gIoRegistersBackup.BLDALPHA_NonGameplay_EVA = gBldalphaData1.evaCoef;
write16(REG_BLDALPHA, gIoRegistersBackup.BLDALPHA_NonGameplay_EVB << 8 | gIoRegistersBackup.BLDALPHA_NonGameplay_EVA);
write16(REG_BLDALPHA, C_16_2_8(gIoRegistersBackup.BLDALPHA_NonGameplay_EVB, gIoRegistersBackup.BLDALPHA_NonGameplay_EVA));
}
}
}
@ -840,9 +943,10 @@ void ConnectionLoadDoors(void)
*/
void ConnectionLockHatchesWithTimer(void)
{
// Lock all doors
gHatchesState.hatchesLockedWithTimer = USHORT_MAX;
ConnectionLockHatches(FALSE);
gDoorUnlockTimer = 0x2;
gDoorUnlockTimer = 2;
}
/**
@ -862,7 +966,7 @@ void ConnectionCheckHatchLockEvents(void)
// Reset locked doors
gHatchesState.hatchesLockedWithEvent = 0;
gHatchesState.unk2 = 0;
gHatchesState.hatchesLockedWithEventUnlockeable = 0;
// Bounds check
if (gCurrentArea >= MAX_AMOUNT_OF_AREAS - 1)
@ -879,16 +983,12 @@ void ConnectionCheckHatchLockEvents(void)
{
// Check event
eventCheck = EventFunction(EVENT_ACTION_CHECKING, pLock->event);
if (pLock->isBefore == TRUE)
{
// Invert event if before
eventCheck ^= pLock->isBefore;
}
else
{
if (pLock->isBefore == 3)
eventCheck ^= TRUE;
}
// Check invert event if before
if (pLock->type == HATCH_LOCK_EVENT_TYPE_BEFORE)
eventCheck ^= TRUE;
else if (pLock->type == HATCH_LOCK_EVENT_TYPE_BEFORE_UNLOCKEABLE)
eventCheck ^= TRUE;
if (eventCheck)
{
@ -913,19 +1013,19 @@ void ConnectionCheckHatchLockEvents(void)
}
}
// Apply lock
if (pLock->isBefore == FALSE)
// Apply lock to correct field
if (pLock->type == HATCH_LOCK_EVENT_TYPE_AFTER)
gHatchesState.hatchesLockedWithEvent |= hatchesToLock;
else if (pLock->isBefore == TRUE)
else if (pLock->type == HATCH_LOCK_EVENT_TYPE_BEFORE)
gHatchesState.hatchesLockedWithEvent |= hatchesToLock;
else if (pLock->isBefore == 2)
gHatchesState.unk2 |= hatchesToLock;
else if (pLock->isBefore == 3)
gHatchesState.unk2 |= hatchesToLock;
else if (pLock->type == HATCH_LOCK_EVENT_TYPE_AFTER_UNLOCKEABLE)
gHatchesState.hatchesLockedWithEventUnlockeable |= hatchesToLock;
else if (pLock->type == HATCH_LOCK_EVENT_TYPE_BEFORE_UNLOCKEABLE)
gHatchesState.hatchesLockedWithEventUnlockeable |= hatchesToLock;
}
// Check actually lock doors
if (gHatchesState.hatchesLockedWithEvent != 0 || gHatchesState.unk2 != 0)
if (gHatchesState.hatchesLockedWithEvent != 0 || gHatchesState.hatchesLockedWithEventUnlockeable != 0)
ConnectionLockHatches(TRUE);
}
@ -943,8 +1043,8 @@ void ConnectionCheckPlayCutsceneDuringTransition(u8 area, u8 dstRoomPlusOne)
// Room 0x1E is the Kraid fight room
if (dstRoomPlusOne == 0x1F && !EventFunction(EVENT_ACTION_CHECKING, EVENT_KRAID_KILLED))
{
FadeMusic(0xA);
FadeAllSounds(0xA);
FadeMusic(CONVERT_SECONDS(1.f / 6));
FadeAllSounds(CONVERT_SECONDS(1.f / 6));
gCurrentCutscene = CUTSCENE_KRAID_RISING;
}
break;
@ -965,7 +1065,6 @@ void ConnectionCheckPlayCutsceneDuringTransition(u8 area, u8 dstRoomPlusOne)
}
break;
// Dumb cases in order to generate jump table
case AREA_BRINSTAR:
case AREA_NORFAIR:
case AREA_RIDLEY:
@ -979,7 +1078,7 @@ void ConnectionCheckPlayCutsceneDuringTransition(u8 area, u8 dstRoomPlusOne)
* @brief 5f7fc | f8 | Checks if a cutscene should play during an door transition on an elevator
*
*/
void ConnectionCheckPlayCutsceneDuringElevator(void)
void ConnectionCheckPlayCutsceneDuringAreaConnection(void)
{
switch (gLastElevatorUsed.route)
{
@ -995,8 +1094,14 @@ void ConnectionCheckPlayCutsceneDuringElevator(void)
break;
case ELEVATOR_ROUTE_BRINSTAR_TO_KRAID:
if (gLastElevatorUsed.direction == ELEVATOR_DIRECTION_UP && EventFunction(EVENT_ACTION_CHECKING, EVENT_KRAID_KILLED) && !EventFunction(EVENT_ACTION_CHECKING, EVENT_EXIT_KRAID_DEMO_PLAYED))
if (gLastElevatorUsed.direction == ELEVATOR_DIRECTION_UP && EventFunction(EVENT_ACTION_CHECKING, EVENT_KRAID_KILLED))
{
if (EventFunction(EVENT_ACTION_CHECKING, EVENT_EXIT_KRAID_DEMO_PLAYED))
{
// Demo already played
break;
}
gCurrentCutscene = CUTSCENE_RIDLEY_IN_SPACE;
ColorFadingStart(COLOR_FADING_CANCEL);

View File

@ -2,9 +2,7 @@
#include "macros.h"
#include "constants/block.h"
#include "constants/connection.h"
#include "constants/text.h"
const struct TankList sNumberOfTanksPerArea[MAX_AMOUNT_OF_AREAS] = {
@ -639,7 +637,7 @@ const struct TankBehavior sTankBehaviors[MAX_AMOUNT_OF_TANK_TYPES] = {
},
};
const u16 sHatchBehaviors[MAX_AMOUNT_OF_HATCH_TYPES][2] = {
const u16 sHatchBehaviors[HATCH_COUNT][2] = {
// 0 : Weakness
// 2 : Health
[HATCH_NONE] = {
@ -670,7 +668,7 @@ const u16 sHatchBehaviors[MAX_AMOUNT_OF_HATCH_TYPES][2] = {
CAA_DAMAGE_TYPE_BEAM | CAA_DAMAGE_TYPE_BOMB_PISTOL | CAA_DAMAGE_TYPE_MISSILE | CAA_DAMAGE_TYPE_SUPER_MISSILE | CAA_DAMAGE_TYPE_POWER_BOMB,
0
},
[HATCH_LOCKED_AND_LOCK_DESTINATION] = {
[HATCH_LOCKED_NAVIGATION] = {
CAA_DAMAGE_TYPE_BEAM | CAA_DAMAGE_TYPE_BOMB_PISTOL | CAA_DAMAGE_TYPE_MISSILE | CAA_DAMAGE_TYPE_SUPER_MISSILE | CAA_DAMAGE_TYPE_POWER_BOMB,
0
},

View File

@ -2,7 +2,6 @@
#include "macros.h"
#include "constants/clipdata.h"
#include "constants/connection.h"
#include "constants/room.h"
const u16 sMovementClipdataValues[16] = {
@ -47,7 +46,7 @@ const u8 sGroundEffectsClipdataValues[8] = {
[BEHAVIOR_TO_GROUND_EFFECT(CLIP_BEHAVIOR_GROUND_EFFECT_UNUSED3)] = GROUND_EFFECT_NONE,
};
const struct ElevatorPair sElevatorRoomPairs[9] = {
const struct ElevatorPair sElevatorRoomPairs[ELEVATOR_ROUTE_COUNT] = {
[ELEVATOR_ROUTE_NONE] = {
.area1 = 11,
.room1 = 0,

View File

@ -12,8 +12,8 @@ const struct HatchData sHatchData_Empty = {
.currentAnimationFrame = 0,
.facingRight = FALSE,
.securityLevel = 0,
.opening = FALSE,
.locked = FALSE,
.state = HATCH_STATE_CLOSED,
.locked = HATCH_LOCK_STATE_UNLOCKED,
.flashingTimer = 0,
.hitTimer = 0,
.hits = 0,

View File

@ -298,7 +298,7 @@ static const u8* const sChozodiaScrolls[] = {
sScroll_Empty
};
const u8* const * const sAreaScrollPointers[AREA_END] = {
const u8* const * const sAreaScrollPointers[AREA_COUNT] = {
[AREA_BRINSTAR] = sBrinstarScrolls,
[AREA_KRAID] = sKraidScrolls,
[AREA_NORFAIR] = sNorfairScrolls,
@ -419,10 +419,10 @@ const BackgroundEffectBehaviorEntry_T* const sBackgroundEffectBehaviorPointers[B
const struct HatchLockEvent* const sHatchLockEventsPointers[MAX_AMOUNT_OF_AREAS - 1] = {
[AREA_BRINSTAR] = sHatchLockEventsBrinstar,
[AREA_KRAID] = sHatchLockEventsKraid,
[AREA_NORFAIR] = sHatchLockEventsNorfair,
[AREA_RIDLEY] = sHatchLockEventsNorfair,
[AREA_TOURIAN] = sHatchLockEventsNorfair,
[AREA_CRATERIA] = sHatchLockEventsNorfair,
[AREA_NORFAIR] = sHatchLockEventsCrateria,
[AREA_RIDLEY] = sHatchLockEventsCrateria,
[AREA_TOURIAN] = sHatchLockEventsCrateria,
[AREA_CRATERIA] = sHatchLockEventsCrateria,
[AREA_CHOZODIA] = sHatchLockEventsChozodia
};

View File

@ -4,26 +4,25 @@
#include "constants/event.h"
#include "constants/clipdata.h"
#include "constants/connection.h"
// 360130
const u8 sHatchTypeTable[MAX_AMOUNT_OF_HATCH_TYPES] = {
[0] = HATCH_NONE,
const u8 sHatchTypeTable[HATCH_COUNT] = {
[BEHAVIOR_TO_DOOR(CLIP_BEHAVIOR_NO_DOOR)] = HATCH_NONE,
[BEHAVIOR_TO_DOOR(CLIP_BEHAVIOR_GRAY_DOOR)] = HATCH_LOCKED,
[BEHAVIOR_TO_DOOR(CLIP_BEHAVIOR_REGULAR_DOOR)] = HATCH_NORMAL,
[BEHAVIOR_TO_DOOR(CLIP_BEHAVIOR_MISSILE_DOOR)] = HATCH_MISSILE,
[BEHAVIOR_TO_DOOR(CLIP_BEHAVIOR_SUPER_MISSILE_DOOR)] = HATCH_SUPER_MISSILE,
[BEHAVIOR_TO_DOOR(CLIP_BEHAVIOR_POWER_BOMB_DOOR)] = HATCH_POWER_BOMB,
[6] = HATCH_LOCKED,
[7] = HATCH_LOCKED_AND_LOCK_DESTINATION,
[7] = HATCH_LOCKED_NAVIGATION,
};
const struct HatchLockEvent sHatchLockEventsBrinstar[1] = {
{
.room = 9,
.event = EVENT_VIEWED_STATUE_ROOM,
.isBefore = TRUE,
.type = HATCH_LOCK_EVENT_TYPE_BEFORE,
.hatchesToLock_0 = FALSE,
.hatchesToLock_1 = TRUE,
.hatchesToLock_2 = FALSE,
@ -47,7 +46,7 @@ const struct HatchLockEvent sHatchLockEventsKraid[1] = {
{
.room = 4,
.event = EVENT_ACID_WORM_KILLED,
.isBefore = TRUE,
.type = HATCH_LOCK_EVENT_TYPE_BEFORE,
.hatchesToLock_0 = TRUE,
.hatchesToLock_1 = FALSE,
.hatchesToLock_2 = FALSE,
@ -67,11 +66,11 @@ const struct HatchLockEvent sHatchLockEventsKraid[1] = {
}
};
const struct HatchLockEvent sHatchLockEventsNorfair[2] = {
const struct HatchLockEvent sHatchLockEventsCrateria[2] = {
{
.room = 0,
.event = EVENT_MOTHER_BRAIN_KILLED,
.isBefore = FALSE,
.type = HATCH_LOCK_EVENT_TYPE_AFTER,
.hatchesToLock_0 = TRUE,
.hatchesToLock_1 = FALSE,
.hatchesToLock_2 = TRUE,
@ -92,7 +91,7 @@ const struct HatchLockEvent sHatchLockEventsNorfair[2] = {
{
.room = 8,
.event = EVENT_BUGS_KILLED,
.isBefore = FALSE,
.type = HATCH_LOCK_EVENT_TYPE_AFTER,
.hatchesToLock_0 = TRUE,
.hatchesToLock_1 = FALSE,
.hatchesToLock_2 = FALSE,
@ -116,7 +115,7 @@ const struct HatchLockEvent sHatchLockEventsChozodia[15] = {
{
.room = 13,
.event = EVENT_MECHA_RIDLEY_KILLED,
.isBefore = FALSE,
.type = HATCH_LOCK_EVENT_TYPE_AFTER,
.hatchesToLock_0 = FALSE,
.hatchesToLock_1 = FALSE,
.hatchesToLock_2 = FALSE,
@ -137,7 +136,7 @@ const struct HatchLockEvent sHatchLockEventsChozodia[15] = {
{
.room = 13,
.event = EVENT_HARD,
.isBefore = FALSE,
.type = HATCH_LOCK_EVENT_TYPE_AFTER,
.hatchesToLock_0 = TRUE,
.hatchesToLock_1 = FALSE,
.hatchesToLock_2 = FALSE,
@ -158,7 +157,7 @@ const struct HatchLockEvent sHatchLockEventsChozodia[15] = {
{
.room = 44,
.event = EVENT_MECHA_RIDLEY_KILLED,
.isBefore = FALSE,
.type = HATCH_LOCK_EVENT_TYPE_AFTER,
.hatchesToLock_0 = FALSE,
.hatchesToLock_1 = TRUE,
.hatchesToLock_2 = FALSE,
@ -179,7 +178,7 @@ const struct HatchLockEvent sHatchLockEventsChozodia[15] = {
{
.room = 46,
.event = EVENT_MECHA_RIDLEY_KILLED,
.isBefore = FALSE,
.type = HATCH_LOCK_EVENT_TYPE_AFTER,
.hatchesToLock_0 = TRUE,
.hatchesToLock_1 = FALSE,
.hatchesToLock_2 = FALSE,
@ -200,7 +199,7 @@ const struct HatchLockEvent sHatchLockEventsChozodia[15] = {
{
.room = 51,
.event = EVENT_MECHA_RIDLEY_KILLED,
.isBefore = FALSE,
.type = HATCH_LOCK_EVENT_TYPE_AFTER,
.hatchesToLock_0 = FALSE,
.hatchesToLock_1 = TRUE,
.hatchesToLock_2 = FALSE,
@ -221,7 +220,7 @@ const struct HatchLockEvent sHatchLockEventsChozodia[15] = {
{
.room = 52,
.event = EVENT_MECHA_RIDLEY_KILLED,
.isBefore = FALSE,
.type = HATCH_LOCK_EVENT_TYPE_AFTER,
.hatchesToLock_0 = TRUE,
.hatchesToLock_1 = FALSE,
.hatchesToLock_2 = TRUE,
@ -242,7 +241,7 @@ const struct HatchLockEvent sHatchLockEventsChozodia[15] = {
{
.room = 53,
.event = EVENT_MECHA_RIDLEY_KILLED,
.isBefore = FALSE,
.type = HATCH_LOCK_EVENT_TYPE_AFTER,
.hatchesToLock_0 = FALSE,
.hatchesToLock_1 = TRUE,
.hatchesToLock_2 = FALSE,
@ -263,7 +262,7 @@ const struct HatchLockEvent sHatchLockEventsChozodia[15] = {
{
.room = 58,
.event = EVENT_MECHA_RIDLEY_KILLED,
.isBefore = FALSE,
.type = HATCH_LOCK_EVENT_TYPE_AFTER,
.hatchesToLock_0 = FALSE,
.hatchesToLock_1 = TRUE,
.hatchesToLock_2 = FALSE,
@ -284,7 +283,7 @@ const struct HatchLockEvent sHatchLockEventsChozodia[15] = {
{
.room = 59,
.event = EVENT_MECHA_RIDLEY_KILLED,
.isBefore = FALSE,
.type = HATCH_LOCK_EVENT_TYPE_AFTER,
.hatchesToLock_0 = FALSE,
.hatchesToLock_1 = TRUE,
.hatchesToLock_2 = FALSE,
@ -305,7 +304,7 @@ const struct HatchLockEvent sHatchLockEventsChozodia[15] = {
{
.room = 60,
.event = EVENT_MECHA_RIDLEY_KILLED,
.isBefore = FALSE,
.type = HATCH_LOCK_EVENT_TYPE_AFTER,
.hatchesToLock_0 = FALSE,
.hatchesToLock_1 = TRUE,
.hatchesToLock_2 = TRUE,
@ -326,7 +325,7 @@ const struct HatchLockEvent sHatchLockEventsChozodia[15] = {
{
.room = 69,
.event = EVENT_MECHA_RIDLEY_KILLED,
.isBefore = FALSE,
.type = HATCH_LOCK_EVENT_TYPE_AFTER,
.hatchesToLock_0 = FALSE,
.hatchesToLock_1 = TRUE,
.hatchesToLock_2 = FALSE,
@ -347,7 +346,7 @@ const struct HatchLockEvent sHatchLockEventsChozodia[15] = {
{
.room = 70,
.event = EVENT_MECHA_RIDLEY_KILLED,
.isBefore = FALSE,
.type = HATCH_LOCK_EVENT_TYPE_AFTER,
.hatchesToLock_0 = FALSE,
.hatchesToLock_1 = TRUE,
.hatchesToLock_2 = FALSE,
@ -368,7 +367,7 @@ const struct HatchLockEvent sHatchLockEventsChozodia[15] = {
{
.room = 71,
.event = EVENT_MECHA_RIDLEY_KILLED,
.isBefore = FALSE,
.type = HATCH_LOCK_EVENT_TYPE_AFTER,
.hatchesToLock_0 = FALSE,
.hatchesToLock_1 = TRUE,
.hatchesToLock_2 = FALSE,
@ -389,7 +388,7 @@ const struct HatchLockEvent sHatchLockEventsChozodia[15] = {
{
.room = 92,
.event = EVENT_MECHA_RIDLEY_KILLED,
.isBefore = FALSE,
.type = HATCH_LOCK_EVENT_TYPE_AFTER,
.hatchesToLock_0 = TRUE,
.hatchesToLock_1 = FALSE,
.hatchesToLock_2 = FALSE,
@ -410,7 +409,7 @@ const struct HatchLockEvent sHatchLockEventsChozodia[15] = {
{
.room = 96,
.event = EVENT_MECHA_RIDLEY_KILLED,
.isBefore = FALSE,
.type = HATCH_LOCK_EVENT_TYPE_AFTER,
.hatchesToLock_0 = FALSE,
.hatchesToLock_1 = TRUE,
.hatchesToLock_2 = FALSE,
@ -430,393 +429,398 @@ const struct HatchLockEvent sHatchLockEventsChozodia[15] = {
}
};
const u8 sEventBasedConnections[MAX_AMOUNT_OF_EVENT_BASED_CONNECTIONS][4] = {
const u8 sEventBasedConnections[41][EVENT_BASED_CONNECTION_FIELD_COUNT] = {
{
[0] = AREA_CHOZODIA, // Source area
[1] = 198, // Source door
[2] = EVENT_HARD, // Event
[3] = 212 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 198,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_HARD,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 212
},
{
[0] = AREA_CHOZODIA, // Source area
[1] = 195, // Source door
[2] = EVENT_HARD, // Event
[3] = 235 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 195,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_HARD,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 235
},
{
[0] = AREA_NORFAIR, // Source area
[1] = 66, // Source door
[2] = EVENT_ENTER_RIDLEY_DEMO_PLAYED, // Event
[3] = 95 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_NORFAIR,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 66,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_ENTER_RIDLEY_DEMO_PLAYED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 95
},
{
[0] = AREA_NORFAIR, // Source area
[1] = 69, // Source door
[2] = EVENT_ENTER_RIDLEY_DEMO_PLAYED, // Event
[3] = 96 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_NORFAIR,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 69,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_ENTER_RIDLEY_DEMO_PLAYED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 96
},
{
[0] = AREA_CRATERIA, // Source area
[1] = 30, // Source door
[2] = EVENT_POWER_GRIP_OBTAINED, // Event
[3] = 29 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CRATERIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 30,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_POWER_GRIP_OBTAINED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 29
},
{
[0] = AREA_CRATERIA, // Source area
[1] = 19, // Source door
[2] = EVENT_CHOZO_PILLAR_FULLY_EXTENDED, // Event
[3] = 47 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CRATERIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 19,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_CHOZO_PILLAR_FULLY_EXTENDED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 47
},
{
[0] = AREA_CHOZODIA, // Source area
[1] = 132, // Source door
[2] = EVENT_SPACE_JUMP_OBTAINED, // Event
[3] = 202 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 132,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_SPACE_JUMP_OBTAINED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 202
},
{
[0] = AREA_CHOZODIA, // Source area
[1] = 136, // Source door
[2] = EVENT_SPACE_JUMP_OBTAINED, // Event
[3] = 203 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 136,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_SPACE_JUMP_OBTAINED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 203
},
{
[0] = AREA_CHOZODIA, // Source area
[1] = 153, // Source door
[2] = EVENT_SPACE_JUMP_OBTAINED, // Event
[3] = 208 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 153,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_SPACE_JUMP_OBTAINED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 208
},
{
[0] = AREA_KRAID, // Source area
[1] = 70, // Source door
[2] = EVENT_KRAID_KILLED, // Event
[3] = 89 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_KRAID,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 70,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_KRAID_KILLED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 89
},
{
[0] = AREA_NORFAIR, // Source area
[1] = 94, // Source door
[2] = EVENT_CATERPILLAR_KILLED, // Event
[3] = 93 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_NORFAIR,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 94,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_CATERPILLAR_KILLED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 93
},
{
[0] = AREA_RIDLEY, // Source area
[1] = 74, // Source door
[2] = EVENT_IMAGO_TUNNEL_DISCOVERED, // Event
[3] = 66 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_RIDLEY,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 74,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_IMAGO_TUNNEL_DISCOVERED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 66
},
{
[0] = AREA_RIDLEY, // Source area
[1] = 43, // Source door
[2] = EVENT_IMAGO_KILLED, // Event
[3] = 59 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_RIDLEY,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 43,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_IMAGO_KILLED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 59
},
{
[0] = AREA_RIDLEY, // Source area
[1] = 63, // Source door
[2] = EVENT_IMAGO_KILLED, // Event
[3] = 65 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_RIDLEY,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 63,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_IMAGO_KILLED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 65
},
{
[0] = AREA_CHOZODIA, // Source area
[1] = 88, // Source door
[2] = EVENT_REPEL_MACHINE_KILLED, // Event
[3] = 93 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 88,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_REPEL_MACHINE_KILLED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 93
},
{
[0] = AREA_CHOZODIA, // Source area
[1] = 91, // Source door
[2] = EVENT_REPEL_MACHINE_KILLED, // Event
[3] = 92 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 91,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_REPEL_MACHINE_KILLED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 92
},
{
[0] = AREA_TOURIAN, // Source area
[1] = 13, // Source door
[2] = EVENT_ESCAPED_ZEBES, // Event
[3] = 20 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_TOURIAN,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 13,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_ESCAPED_ZEBES,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 20
},
{
[0] = AREA_CRATERIA, // Source area
[1] = 27, // Source door
[2] = EVENT_ESCAPED_ZEBES, // Event
[3] = 14 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CRATERIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 27,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_ESCAPED_ZEBES,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 14
},
{
[0] = AREA_CRATERIA, // Source area
[1] = 4, // Source door
[2] = EVENT_ESCAPED_ZEBES, // Event
[3] = 46 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CRATERIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 4,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_ESCAPED_ZEBES,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 46
},
{
[0] = AREA_CHOZODIA, // Source area
[1] = 161, // Source door
[2] = EVENT_MARKER_BETWEEN_ZEBES_AND_MOTHERSHIP, // Event
[3] = 228 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 161,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_MARKER_BETWEEN_ZEBES_AND_MOTHERSHIP,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 228
},
{
[0] = AREA_CHOZODIA, // Source area
[1] = 164, // Source door
[2] = EVENT_MARKER_BETWEEN_ZEBES_AND_MOTHERSHIP, // Event
[3] = 229 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 164,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_MARKER_BETWEEN_ZEBES_AND_MOTHERSHIP,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 229
},
{
[0] = AREA_CHOZODIA, // Source area
[1] = 188, // Source door
[2] = EVENT_MARKER_BETWEEN_ZEBES_AND_MOTHERSHIP, // Event
[3] = 227 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 188,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_MARKER_BETWEEN_ZEBES_AND_MOTHERSHIP,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 227
},
{
[0] = AREA_CHOZODIA, // Source area
[1] = 82, // Source door
[2] = EVENT_FULLY_POWERED_SUIT_OBTAINED, // Event
[3] = 192 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 82,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_FULLY_POWERED_SUIT_OBTAINED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 192
},
{
[0] = AREA_CHOZODIA, // Source area
[1] = 85, // Source door
[2] = EVENT_FULLY_POWERED_SUIT_OBTAINED, // Event
[3] = 191 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 85,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_FULLY_POWERED_SUIT_OBTAINED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 191
},
{
[0] = AREA_CHOZODIA, // Source area
[1] = 46, // Source door
[2] = EVENT_FULLY_POWERED_SUIT_OBTAINED, // Event
[3] = 224 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 46,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_FULLY_POWERED_SUIT_OBTAINED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 224
},
{
[0] = AREA_CHOZODIA, // Source area
[1] = 53, // Source door
[2] = EVENT_FULLY_POWERED_SUIT_OBTAINED, // Event
[3] = 169 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 53,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_FULLY_POWERED_SUIT_OBTAINED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 169
},
{
[0] = AREA_CHOZODIA, // Source area
[1] = 176, // Source door
[2] = EVENT_FULLY_POWERED_SUIT_OBTAINED, // Event
[3] = 201 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 176,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_FULLY_POWERED_SUIT_OBTAINED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 201
},
{
[0] = AREA_CHOZODIA, // Source area
[1] = 57, // Source door
[2] = EVENT_FULLY_POWERED_SUIT_OBTAINED, // Event
[3] = 118 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 57,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_FULLY_POWERED_SUIT_OBTAINED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 118
},
{
[0] = AREA_CHOZODIA, // Source area
[1] = 76, // Source door
[2] = EVENT_FULLY_POWERED_SUIT_OBTAINED, // Event
[3] = 121 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 76,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_FULLY_POWERED_SUIT_OBTAINED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 121
},
{
[0] = AREA_CHOZODIA, // Source area
[1] = 64, // Source door
[2] = EVENT_FULLY_POWERED_SUIT_OBTAINED, // Event
[3] = 120 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 64,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_FULLY_POWERED_SUIT_OBTAINED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 120
},
{
[0] = AREA_CHOZODIA, // Source area
[1] = 67, // Source door
[2] = EVENT_FULLY_POWERED_SUIT_OBTAINED, // Event
[3] = 119 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 67,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_FULLY_POWERED_SUIT_OBTAINED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 119
},
{
[0] = AREA_CHOZODIA, // Source area
[1] = 86, // Source door
[2] = EVENT_FULLY_POWERED_SUIT_OBTAINED, // Event
[3] = 209 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 86,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_FULLY_POWERED_SUIT_OBTAINED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 209
},
{
[0] = AREA_CHOZODIA, // Source area
[1] = 54, // Source door
[2] = EVENT_FULLY_POWERED_SUIT_OBTAINED, // Event
[3] = 148 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 54,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_FULLY_POWERED_SUIT_OBTAINED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 148
},
{
[0] = AREA_CHOZODIA, // Source area
[1] = 79, // Source door
[2] = EVENT_FULLY_POWERED_SUIT_OBTAINED, // Event
[3] = 147 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 79,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_FULLY_POWERED_SUIT_OBTAINED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 147
},
{
[0] = AREA_CHOZODIA, // Source area
[1] = 238, // Source door
[2] = EVENT_FULLY_POWERED_SUIT_OBTAINED, // Event
[3] = 242 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 238,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_FULLY_POWERED_SUIT_OBTAINED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 242
},
{
[0] = AREA_CHOZODIA, // Source area
[1] = 172, // Source door
[2] = EVENT_MECHA_RIDLEY_KILLED, // Event
[3] = 215 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 172,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_MECHA_RIDLEY_KILLED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 215
},
{
[0] = AREA_CHOZODIA, // Source area
[1] = 96, // Source door
[2] = EVENT_MECHA_RIDLEY_KILLED, // Event
[3] = 216 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 96,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_MECHA_RIDLEY_KILLED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 216
},
{
[0] = AREA_CHOZODIA, // Source area
[1] = 100, // Source door
[2] = EVENT_MECHA_RIDLEY_KILLED, // Event
[3] = 217 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 100,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_MECHA_RIDLEY_KILLED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 217
},
{
[0] = AREA_CHOZODIA, // Source area
[1] = 104, // Source door
[2] = EVENT_MECHA_RIDLEY_KILLED, // Event
[3] = 218 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 104,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_MECHA_RIDLEY_KILLED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 218
},
{
[0] = AREA_CHOZODIA, // Source area
[1] = 128, // Source door
[2] = EVENT_MECHA_RIDLEY_KILLED, // Event
[3] = 233 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 128,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_MECHA_RIDLEY_KILLED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 233
},
{
[0] = AREA_CHOZODIA, // Source area
[1] = 152, // Source door
[2] = EVENT_MECHA_RIDLEY_KILLED, // Event
[3] = 234 // Destination door
[EVENT_BASED_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[EVENT_BASED_CONNECTION_FIELD_SOURCE_DOOR] = 152,
[EVENT_BASED_CONNECTION_FIELD_EVENT] = EVENT_MECHA_RIDLEY_KILLED,
[EVENT_BASED_CONNECTION_FIELD_DESTINATION_DOOR] = 234
}
};
const u8 sAreaConnections[26][3] = {
const u8 sAreaConnections[][AREA_CONNECTION_FIELD_COUNT] = {
{
AREA_NORFAIR,
70,
AREA_RIDLEY
[AREA_CONNECTION_FIELD_SOURCE_AREA] = AREA_NORFAIR,
[AREA_CONNECTION_FIELD_SOURCE_DOOR] = 70,
[AREA_CONNECTION_FIELD_DESTINATION_AREA] = AREA_RIDLEY
},
{
AREA_RIDLEY,
0,
AREA_NORFAIR
[AREA_CONNECTION_FIELD_SOURCE_AREA] = AREA_RIDLEY,
[AREA_CONNECTION_FIELD_SOURCE_DOOR] = 0,
[AREA_CONNECTION_FIELD_DESTINATION_AREA] = AREA_NORFAIR
},
{
AREA_BRINSTAR,
57,
AREA_NORFAIR
[AREA_CONNECTION_FIELD_SOURCE_AREA] = AREA_BRINSTAR,
[AREA_CONNECTION_FIELD_SOURCE_DOOR] = 57,
[AREA_CONNECTION_FIELD_DESTINATION_AREA] = AREA_NORFAIR
},
{
AREA_NORFAIR,
0,
AREA_BRINSTAR
[AREA_CONNECTION_FIELD_SOURCE_AREA] = AREA_NORFAIR,
[AREA_CONNECTION_FIELD_SOURCE_DOOR] = 0,
[AREA_CONNECTION_FIELD_DESTINATION_AREA] = AREA_BRINSTAR
},
{
AREA_BRINSTAR,
61,
AREA_TOURIAN
[AREA_CONNECTION_FIELD_SOURCE_AREA] = AREA_BRINSTAR,
[AREA_CONNECTION_FIELD_SOURCE_DOOR] = 61,
[AREA_CONNECTION_FIELD_DESTINATION_AREA] = AREA_TOURIAN
},
{
AREA_TOURIAN,
0,
AREA_BRINSTAR
[AREA_CONNECTION_FIELD_SOURCE_AREA] = AREA_TOURIAN,
[AREA_CONNECTION_FIELD_SOURCE_DOOR] = 0,
[AREA_CONNECTION_FIELD_DESTINATION_AREA] = AREA_BRINSTAR
},
{
AREA_BRINSTAR,
9,
AREA_KRAID
[AREA_CONNECTION_FIELD_SOURCE_AREA] = AREA_BRINSTAR,
[AREA_CONNECTION_FIELD_SOURCE_DOOR] = 9,
[AREA_CONNECTION_FIELD_DESTINATION_AREA] = AREA_KRAID
},
{
AREA_KRAID,
0,
AREA_BRINSTAR
[AREA_CONNECTION_FIELD_SOURCE_AREA] = AREA_KRAID,
[AREA_CONNECTION_FIELD_SOURCE_DOOR] = 0,
[AREA_CONNECTION_FIELD_DESTINATION_AREA] = AREA_BRINSTAR
},
{
AREA_BRINSTAR,
0,
AREA_CRATERIA
[AREA_CONNECTION_FIELD_SOURCE_AREA] = AREA_BRINSTAR,
[AREA_CONNECTION_FIELD_SOURCE_DOOR] = 0,
[AREA_CONNECTION_FIELD_DESTINATION_AREA] = AREA_CRATERIA
},
{
AREA_CRATERIA,
11,
AREA_BRINSTAR
[AREA_CONNECTION_FIELD_SOURCE_AREA] = AREA_CRATERIA,
[AREA_CONNECTION_FIELD_SOURCE_DOOR] = 11,
[AREA_CONNECTION_FIELD_DESTINATION_AREA] = AREA_BRINSTAR
},
{
AREA_CRATERIA,
13,
AREA_TOURIAN
[AREA_CONNECTION_FIELD_SOURCE_AREA] = AREA_CRATERIA,
[AREA_CONNECTION_FIELD_SOURCE_DOOR] = 13,
[AREA_CONNECTION_FIELD_DESTINATION_AREA] = AREA_TOURIAN
},
{
AREA_TOURIAN,
11,
AREA_CRATERIA
[AREA_CONNECTION_FIELD_SOURCE_AREA] = AREA_TOURIAN,
[AREA_CONNECTION_FIELD_SOURCE_DOOR] = 11,
[AREA_CONNECTION_FIELD_DESTINATION_AREA] = AREA_CRATERIA
},
{
AREA_CRATERIA,
17,
AREA_NORFAIR
[AREA_CONNECTION_FIELD_SOURCE_AREA] = AREA_CRATERIA,
[AREA_CONNECTION_FIELD_SOURCE_DOOR] = 17,
[AREA_CONNECTION_FIELD_DESTINATION_AREA] = AREA_NORFAIR
},
{
AREA_NORFAIR,
76,
AREA_CRATERIA
[AREA_CONNECTION_FIELD_SOURCE_AREA] = AREA_NORFAIR,
[AREA_CONNECTION_FIELD_SOURCE_DOOR] = 76,
[AREA_CONNECTION_FIELD_DESTINATION_AREA] = AREA_CRATERIA
},
{
AREA_CRATERIA,
33,
AREA_CHOZODIA
[AREA_CONNECTION_FIELD_SOURCE_AREA] = AREA_CRATERIA,
[AREA_CONNECTION_FIELD_SOURCE_DOOR] = 33,
[AREA_CONNECTION_FIELD_DESTINATION_AREA] = AREA_CHOZODIA
},
{
AREA_CHOZODIA,
150,
AREA_CRATERIA
[AREA_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[AREA_CONNECTION_FIELD_SOURCE_DOOR] = 150,
[AREA_CONNECTION_FIELD_DESTINATION_AREA] = AREA_CRATERIA
},
{
AREA_TOURIAN,
21,
AREA_CRATERIA
[AREA_CONNECTION_FIELD_SOURCE_AREA] = AREA_TOURIAN,
[AREA_CONNECTION_FIELD_SOURCE_DOOR] = 21,
[AREA_CONNECTION_FIELD_DESTINATION_AREA] = AREA_CRATERIA
},
{
AREA_NORFAIR,
108,
AREA_RIDLEY
[AREA_CONNECTION_FIELD_SOURCE_AREA] = AREA_NORFAIR,
[AREA_CONNECTION_FIELD_SOURCE_DOOR] = 108,
[AREA_CONNECTION_FIELD_DESTINATION_AREA] = AREA_RIDLEY
},
{
AREA_RIDLEY,
60,
AREA_NORFAIR
[AREA_CONNECTION_FIELD_SOURCE_AREA] = AREA_RIDLEY,
[AREA_CONNECTION_FIELD_SOURCE_DOOR] = 60,
[AREA_CONNECTION_FIELD_DESTINATION_AREA] = AREA_NORFAIR
},
{
AREA_CHOZODIA,
220,
AREA_CRATERIA
[AREA_CONNECTION_FIELD_SOURCE_AREA] = AREA_CHOZODIA,
[AREA_CONNECTION_FIELD_SOURCE_DOOR] = 220,
[AREA_CONNECTION_FIELD_DESTINATION_AREA] = AREA_CRATERIA
},
{
AREA_CRATERIA,
24,
AREA_CHOZODIA
[AREA_CONNECTION_FIELD_SOURCE_AREA] = AREA_CRATERIA,
[AREA_CONNECTION_FIELD_SOURCE_DOOR] = 24,
[AREA_CONNECTION_FIELD_DESTINATION_AREA] = AREA_CHOZODIA
},
{
AREA_CRATERIA,
49,
AREA_CHOZODIA
[AREA_CONNECTION_FIELD_SOURCE_AREA] = AREA_CRATERIA,
[AREA_CONNECTION_FIELD_SOURCE_DOOR] = 49,
[AREA_CONNECTION_FIELD_DESTINATION_AREA] = AREA_CHOZODIA
},
{
AREA_NORFAIR,
129,
AREA_KRAID
[AREA_CONNECTION_FIELD_SOURCE_AREA] = AREA_NORFAIR,
[AREA_CONNECTION_FIELD_SOURCE_DOOR] = 129,
[AREA_CONNECTION_FIELD_DESTINATION_AREA] = AREA_KRAID
},
{
AREA_KRAID,
103,
AREA_NORFAIR
[AREA_CONNECTION_FIELD_SOURCE_AREA] = AREA_KRAID,
[AREA_CONNECTION_FIELD_SOURCE_DOOR] = 103,
[AREA_CONNECTION_FIELD_DESTINATION_AREA] = AREA_NORFAIR
},
{
AREA_CRATERIA,
51,
AREA_TOURIAN
[AREA_CONNECTION_FIELD_SOURCE_AREA] = AREA_CRATERIA,
[AREA_CONNECTION_FIELD_SOURCE_DOOR] = 51,
[AREA_CONNECTION_FIELD_DESTINATION_AREA] = AREA_TOURIAN
},
{
AREA_NONE,
UCHAR_MAX,
AREA_NONE
[AREA_CONNECTION_FIELD_SOURCE_AREA] = AREA_NONE,
[AREA_CONNECTION_FIELD_SOURCE_DOOR] = UCHAR_MAX,
[AREA_CONNECTION_FIELD_DESTINATION_AREA] = AREA_NONE
}
};
const u8 sHatchesAnimationDurationCounter[6] = {
3, 3, 3, 3, 3, UCHAR_MAX
[0] = CONVERT_SECONDS(.05f),
[1] = CONVERT_SECONDS(.05f),
[2] = CONVERT_SECONDS(.05f),
[3] = CONVERT_SECONDS(.05f),
[4] = CONVERT_SECONDS(.05f),
[5] = UCHAR_MAX
};
const u16 sHatchesTilemapValues[MAX_AMOUNT_OF_HATCH_TYPES] = {
const u16 sHatchesTilemapValues[HATCH_COUNT] = {
[HATCH_NONE] = CLIPDATA_TILEMAP_FLAG | CLIPDATA_TILEMAP_NO_HATCH_DOOR_TOP_LEFT,
[HATCH_UNUSED] = CLIPDATA_TILEMAP_FLAG | CLIPDATA_TILEMAP_GRAY_DOOR_TOP_LEFT,
[HATCH_NORMAL] = CLIPDATA_TILEMAP_FLAG | CLIPDATA_TILEMAP_REGULAR_DOOR_TOP_LEFT,
@ -824,16 +828,16 @@ const u16 sHatchesTilemapValues[MAX_AMOUNT_OF_HATCH_TYPES] = {
[HATCH_SUPER_MISSILE] = CLIPDATA_TILEMAP_FLAG | CLIPDATA_TILEMAP_SUPER_MISSILE_DOOR_TOP_LEFT,
[HATCH_POWER_BOMB] = CLIPDATA_TILEMAP_FLAG | CLIPDATA_TILEMAP_POWER_BOMB_DOOR_TOP_LEFT,
[HATCH_LOCKED] = CLIPDATA_TILEMAP_FLAG | CLIPDATA_TILEMAP_GRAY_DOOR_TOP_LEFT,
[HATCH_LOCKED_AND_LOCK_DESTINATION] = CLIPDATA_TILEMAP_FLAG | CLIPDATA_TILEMAP_CLOSED_DOOR_TOP_LEFT
[HATCH_LOCKED_NAVIGATION] = CLIPDATA_TILEMAP_FLAG | CLIPDATA_TILEMAP_CLOSED_DOOR_TOP_LEFT
};
const u16 sNumberOfHatchLockEventsPerArea[MAX_AMOUNT_OF_AREAS] = {
[AREA_BRINSTAR] = 1,
[AREA_KRAID] = 1,
[AREA_BRINSTAR] = ARRAY_SIZE(sHatchLockEventsBrinstar),
[AREA_KRAID] = ARRAY_SIZE(sHatchLockEventsKraid),
[AREA_NORFAIR] = 0,
[AREA_RIDLEY] = 0,
[AREA_TOURIAN] = 0,
[AREA_CRATERIA] = 2,
[AREA_CHOZODIA] = 15,
[AREA_CRATERIA] = ARRAY_SIZE(sHatchLockEventsCrateria),
[AREA_CHOZODIA] = ARRAY_SIZE(sHatchLockEventsChozodia),
[AREA_DEBUG_1] = 0
};

View File

@ -110,7 +110,7 @@ const u8* const sStatusScreenFlagsOrderPointers[4] = {
[ABILITY_GROUP_MISC] = sStatusScreenMiscFlagsOrder,
};
const u32* const sMinimapDataPointers[AREA_END] = {
const u32* const sMinimapDataPointers[AREA_COUNT] = {
[AREA_BRINSTAR] = sBrinstarMinimap,
[AREA_KRAID] = sKraidMinimap,
[AREA_NORFAIR] = sNorfairMinimap,

View File

@ -33,13 +33,13 @@ u32 GadoraHatchUpdate(u16 xPosition, u16 yPosition, u8 action)
for (i = 0; i < MAX_AMOUNT_OF_HATCHES; i++)
{
if (gHatchData[i].opening)
if (gHatchData[i].state != HATCH_STATE_CLOSED)
continue;
// Try find door at position
if (gHatchData[i].xPosition + xOffset >= SUB_PIXEL_TO_BLOCK(xPosition) &&
gHatchData[i].xPosition - xOffset <= SUB_PIXEL_TO_BLOCK(xPosition) &&
gHatchData[i].yPosition + 3 >= SUB_PIXEL_TO_BLOCK(yPosition) &&
gHatchData[i].yPosition + (HATCH_VERTICAL_SIZE - 1) >= SUB_PIXEL_TO_BLOCK(yPosition) &&
gHatchData[i].yPosition - yOffset <= SUB_PIXEL_TO_BLOCK(yPosition))
{
found = TRUE;

View File

@ -448,9 +448,9 @@ void RoomReset(void)
gEffectYPosition = 0;
gHatchesState.unlocking = FALSE;
gHatchesState.hatchesLockedWithTimer = 0;
gHatchesState.unk = FALSE;
gHatchesState.navigationDoorsUnlocking = FALSE;
gHatchesState.hatchesLockedWithEvent = 0;
gHatchesState.unk2 = FALSE;
gHatchesState.hatchesLockedWithEventUnlockeable = 0;
gDoorUnlockTimer = 0;
pDoor = &sAreaDoorsPointers[gCurrentArea][0];
@ -932,8 +932,8 @@ void RoomUpdateHatchFlashingAnimation(void)
}
}
// Left over code?
if (gHatchesState.unk)
// Left over code from fusion
if (gHatchesState.navigationDoorsUnlocking)
{
gHatchFlashingAnimation.navigation_delay++;
if (gHatchFlashingAnimation.navigation_delay > 7)

View File

@ -1156,14 +1156,9 @@ void SramRead_Arrays(void)
pFile = &sSramEwramPointer->files[gMostRecentSaveFile];
src = &pFile->worldData;
DmaTransfer(3, src->visitedMinimapTiles,
gVisitedMinimapTiles, sizeof(gVisitedMinimapTiles), 16);
DmaTransfer(3, src->hatchesOpened,
gHatchesOpened, sizeof(gHatchesOpened) / 2, 16);
DmaTransfer(3, src->eventsTriggered,
gEventsTriggered, sizeof(gEventsTriggered), 16);
DmaTransfer(3, src->visitedMinimapTiles, gVisitedMinimapTiles, sizeof(gVisitedMinimapTiles), 16);
DmaTransfer(3, src->hatchesOpened, gHatchesOpened, sizeof(gHatchesOpened), 16);
DmaTransfer(3, src->eventsTriggered, gEventsTriggered, sizeof(gEventsTriggered), 16);
BitFill(3, USHORT_MAX, gNeverReformBlocks, sizeof(gNeverReformBlocks), 16);
BitFill(3, USHORT_MAX, gItemsCollected, sizeof(gItemsCollected), 16);
@ -1743,8 +1738,7 @@ void SramWrite_ToEwram_DemoRam(void)
// 0x2037400 = gVisitedMinimapTiles
DmaTransfer(3, (u32*)0x2037400 + gCurrentArea * MINIMAP_SIZE, pFile->visitedMinimapTiles, sizeof(pFile->visitedMinimapTiles), 16);
// 0x2037c00 = gHatchesOpened
DmaTransfer(3, (u8*)0x2037c00 + gCurrentArea * 32, pFile->hatchesOpened, sizeof(pFile->hatchesOpened), 16);
DmaTransfer(3, gHatchesOpened[gCurrentArea], pFile->hatchesOpened, sizeof(pFile->hatchesOpened), 16);
pFile->text[0] = 'A';
pFile->text[1] = 'T';
@ -1780,8 +1774,7 @@ void SramLoad_DemoRamValues(u8 loadSamusData, u8 demoNumber)
// 0x02037400 = gVisitedMinimapTiles
DmaTransfer(3, pDemo->visitedMinimapTiles, (u32*)0x02037400 + gCurrentArea * MINIMAP_SIZE,
sizeof(pDemo->visitedMinimapTiles), 16);
// 0x2037c00 = gHatchesOpened
DmaTransfer(3, pDemo->hatchesOpened, (u16*)0x2037c00 + gCurrentArea * 16, sizeof(pDemo->hatchesOpened), 16);
DmaTransfer(3, pDemo->hatchesOpened, gHatchesOpened[gCurrentArea], sizeof(pDemo->hatchesOpened), 16);
}
else if (loadSamusData == TRUE)
{

View File

@ -534,7 +534,7 @@ void BaristuteDeath(void)
// Set event
EventFunction(EVENT_ACTION_SETTING, EVENT_KRAID_BARISTUTES_KILLED);
// Unlock doors
// Unlock doors
gDoorUnlockTimer = -ONE_THIRD_SECOND;
}
}