diff --git a/include/connection.h b/include/connection.h index 0ef34ece..d75f392b 100644 --- a/include/connection.h +++ b/include/connection.h @@ -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 */ \ No newline at end of file diff --git a/include/constants/clipdata.h b/include/constants/clipdata.h index a6425b68..c2c0448c 100644 --- a/include/constants/clipdata.h +++ b/include/constants/clipdata.h @@ -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 diff --git a/include/constants/connection.h b/include/constants/connection.h index 083b8c22..2ed154d4 100644 --- a/include/constants/connection.h +++ b/include/constants/connection.h @@ -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 */ \ No newline at end of file +#endif /* CONNECTION_CONSTANTS_H */ diff --git a/include/data/block_data.h b/include/data/block_data.h index 262d6e02..5faa68ff 100644 --- a/include/data/block_data.h +++ b/include/data/block_data.h @@ -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]; diff --git a/include/data/clipdata_data.h b/include/data/clipdata_data.h index 4671e2ac..662fe2d0 100644 --- a/include/data/clipdata_data.h +++ b/include/data/clipdata_data.h @@ -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]; diff --git a/include/data/engine_pointers.h b/include/data/engine_pointers.h index d0ce7fd2..9ae4c9ee 100644 --- a/include/data/engine_pointers.h +++ b/include/data/engine_pointers.h @@ -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]; diff --git a/include/data/hatch_data.h b/include/data/hatch_data.h index 9bb8f0e4..5f65504e 100644 --- a/include/data/hatch_data.h +++ b/include/data/hatch_data.h @@ -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]; diff --git a/include/data/menus/internal_pause_screen_data.h b/include/data/menus/internal_pause_screen_data.h index 56a43aa0..6646fdb2 100644 --- a/include/data/menus/internal_pause_screen_data.h +++ b/include/data/menus/internal_pause_screen_data.h @@ -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]; diff --git a/include/macros.h b/include/macros.h index 1626cfae..0f06a683 100644 --- a/include/macros.h +++ b/include/macros.h @@ -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)]) diff --git a/include/structs/connection.h b/include/structs/connection.h index 1cb076cf..3d7eed5e 100644 --- a/include/structs/connection.h +++ b/include/structs/connection.h @@ -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; diff --git a/linker.ld b/linker.ld index dace4205..5a0a35cb 100644 --- a/linker.ld +++ b/linker.ld @@ -33,7 +33,6 @@ SECTIONS { . = 0x00035c00; gNeverReformBlocks = .; . = 0x00036c00; gItemsCollected = .; . = 0x00037400; gVisitedMinimapTiles = .; - . = 0x00037c00; gHatchesOpened = .; . = 0x00037e00; gEventsTriggered = .; . = 0x00037e20; gMinimapTilesGfx = .; . = 0x00038000; gSram = .; diff --git a/src/bg_clip.c b/src/bg_clip.c index 7eb6bbab..7fac2cc3 100644 --- a/src/bg_clip.c +++ b/src/bg_clip.c @@ -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; } } diff --git a/src/connection.c b/src/connection.c index 7e4cc0f7..cf83dd51 100644 --- a/src/connection.c +++ b/src/connection.c @@ -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); diff --git a/src/data/block_data.c b/src/data/block_data.c index 89eb1a87..041f92d7 100644 --- a/src/data/block_data.c +++ b/src/data/block_data.c @@ -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 }, diff --git a/src/data/clipdata_data.c b/src/data/clipdata_data.c index d2797687..1b188838 100644 --- a/src/data/clipdata_data.c +++ b/src/data/clipdata_data.c @@ -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, diff --git a/src/data/empty_datatypes.c b/src/data/empty_datatypes.c index 35ab8fbf..238b84ee 100644 --- a/src/data/empty_datatypes.c +++ b/src/data/empty_datatypes.c @@ -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, diff --git a/src/data/engine_pointers.c b/src/data/engine_pointers.c index a92022bb..e8ee8190 100644 --- a/src/data/engine_pointers.c +++ b/src/data/engine_pointers.c @@ -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 }; diff --git a/src/data/hatch_data.c b/src/data/hatch_data.c index 9e7ce140..331d068e 100644 --- a/src/data/hatch_data.c +++ b/src/data/hatch_data.c @@ -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 }; diff --git a/src/data/menus/internal_pause_screen_data.c b/src/data/menus/internal_pause_screen_data.c index ce9c3dee..6f8303c0 100644 --- a/src/data/menus/internal_pause_screen_data.c +++ b/src/data/menus/internal_pause_screen_data.c @@ -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, diff --git a/src/gadora_hatch.c b/src/gadora_hatch.c index 1be7c32e..b8de0f4f 100644 --- a/src/gadora_hatch.c +++ b/src/gadora_hatch.c @@ -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; diff --git a/src/room.c b/src/room.c index 01e716de..070c1d06 100644 --- a/src/room.c +++ b/src/room.c @@ -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) diff --git a/src/save_file.c b/src/save_file.c index cbcd5cf4..c3f80518 100644 --- a/src/save_file.c +++ b/src/save_file.c @@ -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) { diff --git a/src/sprites_AI/baristute.c b/src/sprites_AI/baristute.c index c743f1e3..d3e1de20 100644 --- a/src/sprites_AI/baristute.c +++ b/src/sprites_AI/baristute.c @@ -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; } }