`ovl_En_Door` docs pass (#1603)

* DoorScheduleResult

* actionVar

* DOOR_DL_

* enums

* ENDOOR_TYPE_SCHEDULE and related stuff

* Name some functions and start figuring out stuff

* defines

* start documenting schedules

* Name Inn doors

* More door schedule naming

* ajar

* Name remaining schedule types

* parameters diagram and some cleanups

* Name renaiming types

* format

* rename some schedules

* Use more static_assert

* name anims

* yeet unrelated stuff

* requestOpen

* Yeet DoorScheduleResult

* whoops

* stuff i missed

* Update src/overlays/actors/ovl_En_Door/scheduleScripts.schl

Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>

* Update src/overlays/actors/ovl_En_Door/z_en_door.h

Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>

* Update src/overlays/actors/ovl_En_Door/z_en_door.h

Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>

* review

* Update src/overlays/actors/ovl_En_Pm/z_en_pm.c

Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>

* Update src/code/z_sub_s.c

Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>

* review

* FindScheduleDoor

---------

Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>
This commit is contained in:
Anghelo Carvajal 2024-04-22 21:34:02 -04:00 committed by GitHub
parent 5143cc4d0d
commit 76fadbd0e9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 845 additions and 417 deletions

View File

@ -922,9 +922,9 @@
<DList Name="gBoulderFragmentsDL" Offset="0x1FA40" />
<Texture Name="gBoulderFragmentsTex" OutName="boulder_fragments" Format="rgba16" Width="32" Height="32" Offset="0x1FBE0" />
<Animation Name="gameplay_keep_Anim_0204B4" Offset="0x204B4" />
<Animation Name="gameplay_keep_Anim_0205A0" Offset="0x205A0" />
<Animation Name="gameplay_keep_Anim_020658" Offset="0x20658" />
<Animation Name="gDoorHumanOpenLeftAnim" Offset="0x204B4" />
<Animation Name="gDoorHumanOpenRightAnim" Offset="0x205A0" />
<Animation Name="gDoorFierceDeityZoraOpenLeftAnim" Offset="0x20658" />
<DList Name="gameplay_keep_DL_020B30" Offset="0x20B30" />
<DList Name="gDoorLeftDL" Offset="0x20BB8" />
<DList Name="gDoorRightDL" Offset="0x20D00" />
@ -937,13 +937,13 @@
<Limb Name="gameplay_keep_Standardlimb_022B00" Type="Standard" EnumName="DOOR_LIMB_3" Offset="0x22B00" />
<Limb Name="gameplay_keep_Standardlimb_022B0C" Type="Standard" EnumName="DOOR_LIMB_4" Offset="0x22B0C" />
<Skeleton Name="gDoorSkel" Type="Normal" LimbType="Standard" LimbNone="DOOR_LIMB_NONE" LimbMax="DOOR_LIMB_MAX" EnumName="DoorLimb" Offset="0x22B28" />
<Animation Name="gameplay_keep_Anim_022BE8" Offset="0x22BE8" />
<Animation Name="gameplay_keep_Anim_022CA8" Offset="0x22CA8" />
<Animation Name="gameplay_keep_Anim_022D90" Offset="0x22D90" />
<Animation Name="gameplay_keep_Anim_022E68" Offset="0x22E68" />
<Animation Name="gDoorFierceDeityZoraOpenRightAnim" Offset="0x22BE8" />
<Animation Name="gDoorGoronOpenLeftAnim" Offset="0x22CA8" />
<Animation Name="gDoorGoronOpenRightAnim" Offset="0x22D90" />
<Animation Name="gDoorDekuOpenLeftAnim" Offset="0x22E68" />
<Blob Name="gameplay_keep_zeroes_unk_00022E78" Size="0xA8" Offset="0x22E78" />
<Animation Name="gameplay_keep_Anim_022FF0" Offset="0x22FF0" />
<Collision Name="gDoorCol" Offset="0x23100" />
<Animation Name="gDoorDekuOpenRightAnim" Offset="0x22FF0" />
<Collision Name="gFramedDoorCol" Offset="0x23100" />
<DList Name="gEffDustDL" Offset="0x23130" />
<DList Name="gEffFlash1DL" Offset="0x23210" />
<DList Name="gEffFlash2DL" Offset="0x23288" />

View File

@ -463,7 +463,7 @@ typedef enum ActorId {
#undef DEFINE_ACTOR_INTERNAL
#undef DEFINE_ACTOR_UNSET
typedef enum {
typedef enum DoorLockType {
/* 0 */ DOORLOCK_NORMAL,
/* 1 */ DOORLOCK_BOSS,
/* 2 */ DOORLOCK_2, // DOORLOCK_NORMAL_SPIRIT on OoT

View File

@ -7,8 +7,8 @@
typedef struct KnobDoorActor {
/* 0x000 */ DynaPolyActor dyna;
/* 0x15C */ SkelAnime skelAnime;
/* 0x1A0 */ u8 animIndex;
/* 0x1A1 */ u8 playOpenAnim;
/* 0x1A0 */ u8 animIndex; // Value between 0 ~ 9. 0 ~ 4 are for left doors while 5 ~ 9 are for right doors. Each value maps to a PlayerTransformation
/* 0x1A1 */ u8 requestOpen; // An actor can set this member to `true` to request this door to open. It must also set `animIndex`
/* 0x1A2 */ s8 objectSlot;
/* 0x1A3 */ s8 dlIndex;
} KnobDoorActor; // size = 0x1A4
@ -19,6 +19,9 @@ typedef struct SlidingDoorActor {
/* 0x15E */ s16 unk_15E;
} SlidingDoorActor; // size = 0x160
#define DOOR_GET_TRANSITION_ID(thisx) ((u16)(thisx)->params >> 10)
#define TRANSITION_ACTOR_PARAMS_INDEX_SHIFT 10
#define TRANSITION_ACTOR_PARAMS(index, params) ((index) << TRANSITION_ACTOR_PARAMS_INDEX_SHIFT) + ((params) & 0x3FF)
#define DOOR_GET_TRANSITION_ID(thisx) ((u16)(thisx)->params >> TRANSITION_ACTOR_PARAMS_INDEX_SHIFT)
#endif

View File

@ -97,7 +97,7 @@ typedef struct ActorPathing {
/* 0x68 */ ActorPathingUpdateFunc setNextPointFunc; // Return true if should compute and update again
} ActorPathing; // size = 0x6C
struct EnDoor* SubS_FindDoor(struct PlayState* play, s32 switchFlag);
struct EnDoor* SubS_FindScheduleDoor(struct PlayState* play, s32 schType);
Gfx* SubS_DrawTransformFlexLimb(struct PlayState* play, s32 limbIndex, void** skeleton, Vec3s* jointTable, OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, TransformLimbDraw transformLimbDraw, Actor* actor, Mtx** mtx, Gfx* gfx);
Gfx* SubS_DrawTransformFlex(struct PlayState* play, void** skeleton, Vec3s* jointTable, s32 dListCount, OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, TransformLimbDraw transformLimbDraw, Actor* actor, Gfx* gfx);

View File

@ -95,7 +95,7 @@ s32 View_InitDistortion(View* view);
s32 View_ClearDistortion(View* view);
s32 View_SetDistortion(View* view, Vec3f orientation, Vec3f scale, f32 speed);
void View_Apply(View* view, s32 mask);
s32 View_Apply(View* view, s32 mask);
s32 View_ApplyOrthoToOverlay(View* view);
s32 View_ApplyPerspectiveToOverlay(View* view);
s32 View_UpdateViewingMatrix(View* view);

View File

@ -30,6 +30,7 @@ struct Actor* D_801ED920; // 2 funcs. 1 out of z_actor
#include "z64actor.h"
#include "z64door.h"
#include "z64circle_tex.h"
#include "z64horse.h"
#include "z64malloc.h"
@ -3428,7 +3429,7 @@ void Actor_SpawnTransitionActors(PlayState* play, ActorContext* actorCtx) {
if (Actor_SpawnAsChildAndCutscene(actorCtx, play, transitionActorList->id & 0x1FFF,
transitionActorList->pos.x, transitionActorList->pos.y,
transitionActorList->pos.z, 0, rotY, 0,
(i << 0xA) + (transitionActorList->params & 0x3FF),
TRANSITION_ACTOR_PARAMS(i, transitionActorList->params),
transitionActorList->rotY & 0x7F, HALFDAYBIT_ALL, 0) != NULL) {
transitionActorList->id = -transitionActorList->id;
}

View File

@ -191,7 +191,7 @@ void func_800F0BB4(EnHy* enHy, PlayState* play, EnDoor* door, s16 arg3, s16 arg4
enHy->skelAnime.prevTransl = enHy->skelAnime.jointTable[LIMB_ROOT_POS];
enHy->skelAnime.moveFlags |= (ANIM_FLAG_UPDATE_Y | ANIM_FLAG_1);
AnimationContext_SetMoveActor(play, &enHy->actor, &enHy->skelAnime, 1.0f);
door->knobDoor.playOpenAnim = true;
door->knobDoor.requestOpen = true;
door->knobDoor.animIndex = animIndex;
}

View File

@ -108,7 +108,7 @@ s32 Object_GetSlot(ObjectContext* objectCtx, s16 objectId) {
}
}
return -1;
return OBJECT_SLOT_NONE;
}
s32 Object_IsLoaded(ObjectContext* objectCtx, s32 slot) {

View File

@ -15,9 +15,10 @@ Vec3f gOneVec3f = { 1.0f, 1.0f, 1.0f };
s32 D_801C5DBC[] = { 0, 1 }; // Unused
/**
* Finds the first EnDoor instance with doorType == ENDOOR_TYPE_5 and the specified switchFlag.
* Finds the first EnDoor instance of type `ENDOOR_TYPE_SCHEDULE` and the specified schType (a value from the
* EnDoorScheduleType enum).
*/
EnDoor* SubS_FindDoor(PlayState* play, s32 switchFlag) {
EnDoor* SubS_FindScheduleDoor(PlayState* play, s32 schType) {
Actor* actor = NULL;
EnDoor* door;
@ -29,7 +30,7 @@ EnDoor* SubS_FindDoor(PlayState* play, s32 switchFlag) {
break;
}
if ((door->doorType == ENDOOR_TYPE_5) && (door->switchFlag == (u8)switchFlag)) {
if ((door->doorType == ENDOOR_TYPE_SCHEDULE) && (door->typeVar.schType == (u8)schType)) {
break;
}

View File

@ -299,13 +299,13 @@ s32 View_StepDistortion(View* view, Mtx* projectionMtx) {
/**
* Apply view to POLY_OPA_DISP, POLY_XLU_DISP (and OVERLAY_DISP if ortho)
*/
void View_Apply(View* view, s32 mask) {
s32 View_Apply(View* view, s32 mask) {
mask = (view->flags & mask) | (mask >> 4);
if (mask & VIEW_PROJECTION_ORTHO) {
View_ApplyOrtho(view);
return View_ApplyOrtho(view);
} else {
View_ApplyPerspective(view);
return View_ApplyPerspective(view);
}
}

View File

@ -71,7 +71,7 @@ typedef enum AnjuScheduleResult {
/* 20 */ ANJU_SCH_20,
// 12:00 ~ 12:15, Day 1 and Day 2 (if did had the Midnight meeting). Give lunch to Granny
/* 21 */ ANJU_SCH_GIVE_LUNCH_TO_GRANNY,
// Day 3, 06:00 ~ 11:00. Sweeping the Suite room. TODO: maybe rename to "cleaning Suite room"?
// Day 3, 06:00 ~ 11:00. Sweeping the Large Suite.
/* 22 */ ANJU_SCH_SWEEPING,
// Day 1, 00:00 ~ 06:00. Waiting for player at the kitchen to have the Midnight meeting.
/* 23 */ ANJU_SCH_MIDNIGHT_MEETING,
@ -444,24 +444,24 @@ Actor* func_80B53A7C(EnAn* this, PlayState* play, u8 actorCategory, s16 actorId)
return actorIter;
}
EnDoor* EnAn_FindDoor(PlayState* play, AnjuScheduleResult scheduleOutputResult) {
s32 switchFlag;
EnDoor* EnAn_FindScheduleDoor(PlayState* play, AnjuScheduleResult scheduleOutputResult) {
EnDoorScheduleType schType;
switch (scheduleOutputResult) {
case ANJU_SCH_DOOR_26:
case ANJU_SCH_DOOR_27:
switchFlag = 0xD;
schType = ENDOOR_SCH_TYPE_INN_GRANNYS;
break;
case ANJU_SCH_DOOR_33:
case ANJU_SCH_DOOR_34:
case ANJU_SCH_DOOR_37:
case ANJU_SCH_DOOR_38:
switchFlag = 0xB;
schType = ENDOOR_SCH_TYPE_INN_MAIN_ENTRANCE;
break;
case ANJU_SCH_DOOR_36:
switchFlag = 0x10;
schType = ENDOOR_SCH_TYPE_INN_LARGE_SUITE;
break;
case ANJU_SCH_DOOR_28:
@ -471,14 +471,14 @@ EnDoor* EnAn_FindDoor(PlayState* play, AnjuScheduleResult scheduleOutputResult)
case ANJU_SCH_DOOR_32:
case ANJU_SCH_DOOR_35:
case ANJU_SCH_DOOR_39:
switchFlag = 0xE;
schType = ENDOOR_SCH_TYPE_INN_STAFF_ROOM;
break;
default:
return NULL;
}
return SubS_FindDoor(play, switchFlag);
return SubS_FindScheduleDoor(play, schType);
}
/**
@ -1933,7 +1933,7 @@ s32 EnAn_ProcessSchedule_Door(EnAn* this, PlayState* play, ScheduleOutput* sched
s32 ret = false;
this->timePath = NULL;
door = EnAn_FindDoor(play, scheduleOutput->result);
door = EnAn_FindScheduleDoor(play, scheduleOutput->result);
limit = sSearchTimePathLimit[scheduleOutput->result];
if (limit >= 0) {
@ -2437,7 +2437,7 @@ s32 EnAn_HandleSch_InteractActor(EnAn* this, PlayState* play) {
}
s32 EnAn_HandleSch_Door(EnAn* this, PlayState* play) {
EnDoor* door = EnAn_FindDoor(play, this->scheduleResult);
EnDoor* door = EnAn_FindScheduleDoor(play, this->scheduleResult);
Vec3f sp38;
f32 distance;
s32 pad;

View File

@ -1,231 +1,310 @@
D_808675D0 {
/**
* Schedules for EnDoor
*
* EnDoor uses the schedule system to determine if it should be open or closed
* (and prompt a message) when the Player tries to open it.
*
* If a schedule returns `none` it means the door should be openable by Player.
* A non-`none` value means the door should be closed and prompt a message.
* Which message is used is determined by using the returned value from the
* schedule as an offset into text id 0x1800.
*/
// Swordsman's School
sDoorSch_SwordsmansSchool {
// The Swordsman's School is closed between 23:00 ~ 00:00 and says
// the teacher is "focusing his spirit"
if_day (3) {
not if_time_range (6, 0, 23, 0) {
not if_time_range (0, 0, 6, 0) {
return_s (7)
return_s (0x7)
}
}
}
return_none
}
D_808675E4 {
// Post Office
sDoorSch_PostOffice {
if_before_time (9, 0) {
return_s (9)
// Closed between 00:00 ~ 09:00
return_s (0x9)
} else if_before_time (12, 0) {
branch (label_0x1D)
// Delivering mail between 09:00 ~ 12:00
branch (delivering_mail_msg)
} else {
if_day (1) {
branch (label_0x0E)
label_0x0E:
if_before_time (13, 0) {
branch (label_0x1C)
// Open between 12:00 ~ 13:00
branch (open_post_office)
} else if_before_time (15, 0) {
branch (label_0x1D)
} else if_before_time (0, 0) {
branch (label_0x1C)
} else {
return_s (9)
// Delivering mail between 13:00 ~ 15:00
branch (delivering_mail_msg)
} else if_since_time (0, 0) {
// Closed between 00:00 ~ 09:00
return_s (0x9)
}
// Open between 15:00 ~ 00:00
label_0x1C:
open_post_office:
return_none
label_0x1D:
return_s (8)
delivering_mail_msg:
// "Out delivering mail"
return_s (0x8)
} else if_day (2) {
if_week_event_reg (WEEKEVENTREG_28_08) {
// Related to letter to Kafei
if_before_time (13, 0) {
branch (label_0x1C)
// Open between 12:00 ~ 13:00
branch (open_post_office)
} else if_before_time (17, 0) {
branch (label_0x1D)
} else if_before_time (0, 0) {
branch (label_0x1C)
// Delivering mail between 13:00 ~ 17:00
branch (delivering_mail_msg)
} else if_since_time (0, 0) {
// Closed between 00:00 ~ 09:00
return_s (0x9)
} else {
return_s (9)
// Open between 15:00 ~ 00:00
branch (open_post_office)
}
} else if_since_time (13, 0) {
return_s (9)
} else {
if_since_time (13, 0) {
//! @bug The in-game message expliclty says the office should be open up to 15:00 (3 p.m.)
//! Maybe it was a typo between 3 (p.m.) and 13?
// Closed between 13:00 ~ 09:00
return_s (0x9)
} else {
// Open between 12:00 ~ 13:00
return_none
}
}
} else { // day 3
if_before_time (13, 0) {
// Open between 12:00 ~ 13:00
branch (open_post_office)
} else if_before_time (13, 0) {
//! @bug? unreachable code
branch (delivering_mail_msg)
} else if_before_time (18, 0) {
// Closed between 13:00 ~ 18:00
return_s (0x9)
} else {
// Open since 18:00
return_none
}
} else if_before_time (13, 0) {
branch (label_0x1C)
} else if_before_time (13, 0) {
branch (label_0x1D)
} else if_before_time (18, 0) {
return_s (9)
} else {
return_none
}
}
}
D_80867634 {
// Lottery Shop
sDoorSch_LotteryShop {
// Open between 06:00 ~ 23:00
if_time_range (6, 0, 23, 0) {
return_none
} else {
return_s (28)
return_s (0x1C)
}
}
D_80867640 {
// Trading Post
sDoorSch_TradingPost {
if_time_range (21, 0, 22, 0) {
return_s (11)
return_s (0xB)
} else {
return_none
}
}
D_8086764C {
// Curiosity Shop
sDoorSch_CuriosityShop {
not if_time_range (22, 0, 5, 0) {
return_s (10)
return_s (0xA)
} else {
return_none
}
}
D_80867658 {
// Laundry Pool
sDoorSch_LaundryPool {
if_day (2) {
not if_week_event_reg (WEEKEVENTREG_28_08) {
return_s (12)
return_s (0xC)
} else if_time_range (15, 10, 22, 0) {
return_none
} else {
return_s (12)
return_s (0xC)
}
}
if_day (3) {
if_since_time (13, 0) {
not if_week_event_reg (WEEKEVENTREG_51_08) {
return_s (12)
return_s (0xC)
} else if_since_time (22, 0) {
return_s (12)
return_s (0xC)
} else {
return_none
}
}
}
return_s (12)
// Day 1
return_s (0xC)
}
D_80867684 {
// Bomb Shop
sDoorSch_BombShop {
return_none
}
D_80867688 {
// Town Shooting Gallery
sDoorSch_TownShootingGallery {
if_since_time (22, 0) {
return_s (15)
return_s (0xF)
} else {
return_none
}
}
D_80867690 {
// Treasure Chest Shop
sDoorSch_TreasureChestShop {
if_since_time (22, 0) {
return_s (16)
return_s (0x10)
} else {
return_none
}
}
D_80867698 {
// Honey & Darling's Shop
sDoorSch_HoneyDarlingShop {
if_since_time (22, 0) {
return_s (17)
return_s (0x11)
} else {
return_none
}
}
D_808676A0 {
// Milk Bar
sDoorSch_MilkBar {
if_time_range (10, 0, 21, 0) {
// Open without requirements between 10:00 ~ 21:00
return_none
} else if_time_range (22, 0, 5, 0) {
if_misc (SCHEDULE_CHECK_MISC_MASK_ROMANI) {
return_s (33)
// Player is a member of the Milk bar and can enter
return_s (0x21)
} else {
return_s (34)
// "Show you are a member"
return_s (0x22)
}
} else {
return_s (18)
// Closed between 21:00 ~ 22:00 and 05:00 ~ 10:00
// Message saying when the Bar opens
return_s (0x12)
}
}
D_808676B8 {
// Stock Pot Inn: Main door
sDoorSch_InnMainEntrance {
not if_misc (SCHEDULE_CHECK_MISC_ROOM_KEY) {
if_day (3) {
// Door is unlocked at night 3
if_before_time (8, 0) {
return_s (19)
return_s (0x13)
} else {
return_none
}
} else if_time_range (8, 0, 20, 30) {
return_none
} else {
return_s (19)
not if_time_range (8, 0, 20, 30) {
return_s (0x13)
} else {
return_none
}
}
} else {
// If player has the Room Key then they can enter the Inn at any time
return_none
}
}
D_808676D0 {
// Stock Pot Inn: Entrance at the second floor
sDoorSch_InnUpperEntrance {
return_none
}
D_808676D4 {
// Stock Pot Inn: Granny's door
sDoorSch_InnGrannys {
return_none
}
D_808676D8 {
// Stock Pot Inn: Staff room door
sDoorSch_InnStaffRoom {
// It is open at night 3
if_day (3) {
if_since_time (18, 0) {
return_none
}
}
return_s (20)
// "Only employees can enter"
return_s (0x14)
}
D_808676E4 {
// Stock Pot Inn: Knife Chamber door
sDoorSch_InnKnifeChamber {
not if_misc (SCHEDULE_CHECK_MISC_ROOM_KEY) {
return_s (22)
return_s (0x16)
} else {
return_none
}
}
D_808676EC {
// Stock Pot Inn: Large Suite door
sDoorSch_InnLargeSuite {
return_none
}
D_808676F0 {
// The Mayor's Residence: Main entrance
sDoorSch_MayorsResidenceMainEntrance {
// Day 1 and 2: Open between 10:00 ~ 20:00
// Day 3: Open since 10:00
if_day (3) {
if_since_time (10, 0) {
label_0x8:
open_residence:
return_none
} else {
branch (label_0xF)
branch (closed_residence)
}
} else {
if_time_range (10, 0, 20, 0) {
branch (label_0x8)
branch (open_residence)
} else {
label_0xF:
return_s (21)
closed_residence:
return_s (0x15)
}
}
}
D_80867704 {
// The Mayor's Residence: Mayor Dotour
sDoorSch_MayorsResidenceMayorDotour {
return_none
}
D_80867708 {
// The Mayor's Residence: Madame Aroma
sDoorSch_MayorsResidenceMadameAroma {
return_none
}
D_8086770C {
// The Mayor's Residence: Bedroom
sDoorSch_MayorsResidenceBedroom {
return_none
}
@ -233,50 +312,70 @@ D_80867710 {
return_none
}
D_80867714 {
// Romani Ranch: Mama's House
sDoorSch_RomaniRanchMamasHouse {
if_since_time (20, 0) {
return_s (23)
return_s (0x17)
} else {
return_none
}
}
D_8086771C {
// Romani Ranch: Barn
sDoorSch_RomaniRanchBarn {
if_day (1) {
if_since_time (2, 30) {
return_s (24)
// Cremia is in the Barn during the Alien invasion
// "locked from inside" message
return_s (0x18)
} else {
label_0x0A:
open_barn:
return_none
}
} else if_day (3) {
if_since_time (20, 0) {
return_s (12)
// Cremia and Romani left the Barn locked on night 3.
// Them leaving the Barn at night 3 only happens if the
// aliens were defeated on night 1, so if player did not
// do that then the door would be mysteriously locked
// "locked door" message
return_s (0xC)
} else {
branch (label_0x0A)
branch (open_barn)
}
} else {
branch (label_0x0A)
} else { // day 2
branch (open_barn)
}
}
D_80867734 {
// Romani Ranch: Cucco Shack
sDoorSch_RomaniRanchCuccoShack {
// Closed between 20:00 ~ 06:00
if_since_time (20, 0) {
return_s (25)
return_s (0x19)
} else {
return_none
}
}
D_8086773C {
// Romani Ranch: Doggy Racetrack
sDoorSch_RomaniRanchDoggyRacetrack {
// Closed between 20:00 ~ 06:00
if_since_time (20, 0) {
return_s (26)
return_s (0x1A)
} else {
return_none
}
}
D_80867744 {
// Romani Ranch: Bedroom
sDoorSch_RomaniRanchBedroom {
//! @bug? All the codepaths that lead to a non none return are unreachable
//! in the base game, since nothing sets WEEKEVENTREG_99_80 and the player
//! is kicked out at 20:00
not if_day (2) {
branch (label_0x08)
} else {
@ -287,7 +386,7 @@ D_80867744 {
if_before_time (20, 0) {
branch (label_0x14)
} else {
return_s (27)
return_s (0x1B)
}
}
}
@ -296,23 +395,24 @@ D_80867744 {
if_before_time (18, 0) {
branch (label_0x14)
} else {
return_s (27)
return_s (0x1B)
}
label_0x14:
return_none
}
D_8086775C {
// Ikana Canyom: Music Box House
sDoorSch_IkanaCanyonMusicBoxHouse {
not if_week_event_reg (WEEKEVENTREG_CLEARED_STONE_TOWER_TEMPLE) {
not if_week_event_reg (WEEKEVENTREG_75_20) {
not if_week_event_reg (WEEKEVENTREG_14_04) {
return_s (29)
return_s (0x1D)
} else not if_week_event_reg (WEEKEVENTREG_59_01) {
if_week_event_reg (WEEKEVENTREG_61_02) {
return_s (31)
return_s (0x1F)
} else {
return_s (30)
return_s (0x1E)
}
} else {
return_none
@ -323,11 +423,13 @@ D_8086775C {
return_none
}
D_80867778 {
return_s (32)
// Ikana Graveyard: Dampé's House
sDoorSch_DampesHouse {
return_s (0x20)
}
D_8086777C{
// Magic Hags' Potion Shop
sDoorSch_MagicHagsPotionShop{
return_none
}
@ -335,9 +437,10 @@ D_80867780 {
return_none
}
D_80867784 {
// Swamp Shooting Gallery
sDoorSch_SwampShootingGallery {
if_since_time (22, 0) {
return_s (35)
return_s (0x23)
} else {
return_none
}

View File

@ -5,6 +5,9 @@
*/
#include "z_en_door.h"
#include "libc/assert.h"
#include "objects/object_kinsta2_obj/object_kinsta2_obj.h"
#include "objects/object_dor01/object_dor01.h"
#include "objects/object_dor02/object_dor02.h"
@ -21,6 +24,9 @@
#define FLAGS (ACTOR_FLAG_10)
#define DOOR_AJAR_SLAM_RANGE 120.0f
#define DOOR_AJAR_OPEN_RANGE (2 * DOOR_AJAR_SLAM_RANGE)
#define THIS ((EnDoor*)thisx)
void EnDoor_Init(Actor* thisx, PlayState* play2);
@ -28,22 +34,56 @@ void EnDoor_Destroy(Actor* thisx, PlayState* play);
void EnDoor_Update(Actor* thisx, PlayState* play);
void EnDoor_Draw(Actor* thisx, PlayState* play);
void func_80866B20(EnDoor* this, PlayState* play);
void func_8086704C(EnDoor* this, PlayState* play);
void func_80866F94(EnDoor* this, PlayState* play);
void func_80867080(EnDoor* this, PlayState* play);
void func_80867144(EnDoor* this, PlayState* play);
void func_808670F0(EnDoor* this, PlayState* play);
void func_80866A5C(EnDoor* this, PlayState* play);
void EnDoor_Idle(EnDoor* this, PlayState* play);
void EnDoor_AjarWait(EnDoor* this, PlayState* play);
void EnDoor_OpenScheduleActor(EnDoor* this, PlayState* play);
void EnDoor_AjarOpen(EnDoor* this, PlayState* play);
void EnDoor_Open(EnDoor* this, PlayState* play);
void EnDoor_AjarClose(EnDoor* this, PlayState* play);
void EnDoor_WaitForObject(EnDoor* this, PlayState* play);
#include "src/overlays/actors/ovl_En_Door/scheduleScripts.schl.inc"
ScheduleScript* D_8086778C[] = {
D_808675D0, D_808675E4, D_80867634, D_80867640, D_8086764C, D_80867658, D_80867684, D_80867688,
D_80867690, D_80867698, D_808676A0, D_808676B8, D_808676D0, D_808676D4, D_808676D8, D_808676E4,
D_808676EC, D_808676F0, D_80867704, D_80867708, D_8086770C, D_80867710, D_80867714, D_8086771C,
D_80867734, D_8086773C, D_80867744, D_8086775C, D_80867778, D_8086777C, D_80867780, D_80867784,
/**
* A schedule returning none means the door can be used normally.
* Otherwise the result will be used as an offset relative to text message 0x1800
*/
ScheduleScript* sDoorSchedules[] = {
sDoorSch_SwordsmansSchool, // ENDOOR_SCH_TYPE_SWORDSMANS_SCHOOL
sDoorSch_PostOffice, // ENDOOR_SCH_TYPE_POST_OFFICE
sDoorSch_LotteryShop, // ENDOOR_SCH_TYPE_LOTTERY_SHOP
sDoorSch_TradingPost, // ENDOOR_SCH_TYPE_TRADING_POST
sDoorSch_CuriosityShop, // ENDOOR_SCH_TYPE_CURIOSITY_SHOP
sDoorSch_LaundryPool, // ENDOOR_SCH_TYPE_LAUNDRY_POOL
sDoorSch_BombShop, // ENDOOR_SCH_TYPE_BOMB_SHOP
sDoorSch_TownShootingGallery, // ENDOOR_SCH_TYPE_TOWN_SHOOTING_GALLERY
sDoorSch_TreasureChestShop, // ENDOOR_SCH_TYPE_TREASURE_CHEST_SHOP
sDoorSch_HoneyDarlingShop, // ENDOOR_SCH_TYPE_HONEY_DARLING_SHOP
sDoorSch_MilkBar, // ENDOOR_SCH_TYPE_MILK_BAR
sDoorSch_InnMainEntrance, // ENDOOR_SCH_TYPE_INN_MAIN_ENTRANCE
sDoorSch_InnUpperEntrance, // ENDOOR_SCH_TYPE_INN_UPPER_ENTRANCE
sDoorSch_InnGrannys, // ENDOOR_SCH_TYPE_INN_GRANNYS
sDoorSch_InnStaffRoom, // ENDOOR_SCH_TYPE_INN_STAFF_ROOM
sDoorSch_InnKnifeChamber, // ENDOOR_SCH_TYPE_INN_KNIFE_CHAMBER
sDoorSch_InnLargeSuite, // ENDOOR_SCH_TYPE_INN_LARGE_SUITE
sDoorSch_MayorsResidenceMainEntrance, // ENDOOR_SCH_TYPE_MAYORS_RESIDENCE_MAIN_ENTRANCE
sDoorSch_MayorsResidenceMayorDotour, // ENDOOR_SCH_TYPE_MAYORS_RESIDENCE_MAYOR_DOTOUR
sDoorSch_MayorsResidenceMadameAroma, // ENDOOR_SCH_TYPE_MAYORS_RESIDENCE_MADAME_AROMA
sDoorSch_MayorsResidenceBedroom, // ENDOOR_SCH_TYPE_MAYORS_RESIDENCE_BEDROOM
D_80867710, // ENDOOR_SCH_TYPE_21
sDoorSch_RomaniRanchMamasHouse, // ENDOOR_SCH_TYPE_ROMANI_RANCH_MAMAS_HOUSE
sDoorSch_RomaniRanchBarn, // ENDOOR_SCH_TYPE_ROMANI_RANCH_BARN
sDoorSch_RomaniRanchCuccoShack, // ENDOOR_SCH_TYPE_ROMANI_RANCH_CUCCO_SHACK
sDoorSch_RomaniRanchDoggyRacetrack, // ENDOOR_SCH_TYPE_ROMANI_RANCH_DOGGY_RACETRACK
sDoorSch_RomaniRanchBedroom, // ENDOOR_SCH_TYPE_ROMANI_RANCH_BEDROOM
sDoorSch_IkanaCanyonMusicBoxHouse, // ENDOOR_SCH_TYPE_IKANA_CANYON_MUSIC_BOX_HOUSE
sDoorSch_DampesHouse, // ENDOOR_SCH_TYPE_DAMPES_HOUSE
sDoorSch_MagicHagsPotionShop, // ENDOOR_SCH_TYPE_MAGIC_HAGS_POTION_SHOP
D_80867780, // ENDOOR_SCH_TYPE_30
sDoorSch_SwampShootingGallery, // ENDOOR_SCH_TYPE_SWAMP_SHOOTING_GALLERY
};
static_assert(ARRAY_COUNT(sDoorSchedules) == ENDOOR_SCH_TYPE_MAX,
"The entry count of `sDoorSchedules` should match the `EnDoorScheduleType` enum");
ActorInit En_Door_InitVars = {
/**/ ACTOR_EN_DOOR,
@ -57,63 +97,155 @@ ActorInit En_Door_InitVars = {
/**/ EnDoor_Draw,
};
typedef struct {
typedef enum EnDoorDListIndex {
/* 0 */ DOOR_DL_DEFAULT,
/* 1 */ DOOR_DL_WOODFALL,
/* 2 */ DOOR_DL_OBSERVATORY_LAB,
/* 3 */ DOOR_DL_ZORA_HALL,
/* 4 */ DOOR_DL_SWAMP,
/* 5 */ DOOR_DL_MAGIC_HAG_POTION_SHOP,
/* 6 */ DOOR_DL_LOTTERY_CURIOSITY_SHIP_MAYOR_HOUSE,
/* 7 */ DOOR_DL_POST_OFFICE_TRAIDING_POST,
/* 8 */ DOOR_DL_INN_SCHOOL,
/* 9 */ DOOR_DL_MILK_BAR,
/* 10 */ DOOR_DL_MUSIC_BOX,
/* 11 */ DOOR_DL_PIRATES_FORTESS,
/* 12 */ DOOR_DL_OCEANSIDE_SPIDER_HOUSE,
/* 13 */ DOOR_DL_DEFAULT_FIELD_KEEP,
/* 14 */ DOOR_DL_MAX
} EnDoorDListIndex;
typedef struct EnDoorInfo {
/* 0x0 */ s16 sceneId;
/* 0x2 */ u8 dListIndex;
/* 0x4 */ s16 objectId;
} EnDoorInfo; // size = 0x6
// TODO: This enum feels kinda overkill...
typedef enum EnDoorObjectInfoIndex {
/* 0 */ DOOR_OBJKIND_DEFAULT,
/* 0 */ DOOR_OBJINFO_0 = DOOR_OBJKIND_DEFAULT,
/* 1 */ DOOR_OBJINFO_1,
/* 2 */ DOOR_OBJINFO_2,
/* 3 */ DOOR_OBJINFO_3,
/* 4 */ DOOR_OBJINFO_4,
/* 5 */ DOOR_OBJINFO_5,
/* 6 */ DOOR_OBJINFO_6,
/* 7 */ DOOR_OBJINFO_7,
/* 8 */ DOOR_OBJINFO_8,
/* 9 */ DOOR_OBJINFO_9,
/* 10 */ DOOR_OBJINFO_10,
/* 11 */ DOOR_OBJINFO_11,
/* 12 */ DOOR_OBJINFO_12,
/* 13 */ DOOR_OBJINFO_13,
/* 14 */ DOOR_OBJINFO_14,
/* 15 */ DOOR_OBJKIND_KEEP,
/* 15 */ DOOR_OBJINFO_15 = DOOR_OBJKIND_KEEP,
/* 16 */ DOOR_OBJINFO_16,
/* 17 */ DOOR_OBJKIND_SCHEDULE,
/* 17 */ DOOR_OBJINFO_17 = DOOR_OBJKIND_SCHEDULE, // ENDOOR_SCH_TYPE_SWORDSMANS_SCHOOL
/* 18 */ DOOR_OBJINFO_18, // ENDOOR_SCH_TYPE_POST_OFFICE
/* 19 */ DOOR_OBJINFO_19, // ENDOOR_SCH_TYPE_LOTTERY_SHOP
/* 20 */ DOOR_OBJINFO_20, // ENDOOR_SCH_TYPE_TRADING_POST
/* 21 */ DOOR_OBJINFO_21, // ENDOOR_SCH_TYPE_CURIOSITY_SHOP
/* 22 */ DOOR_OBJINFO_22, // ENDOOR_SCH_TYPE_LAUNDRY_POOL
/* 23 */ DOOR_OBJINFO_23, // ENDOOR_SCH_TYPE_BOMB_SHOP
/* 24 */ DOOR_OBJINFO_24, // ENDOOR_SCH_TYPE_TOWN_SHOOTING_GALLERY
/* 25 */ DOOR_OBJINFO_25, // ENDOOR_SCH_TYPE_TREASURE_CHEST_SHOP
/* 26 */ DOOR_OBJINFO_26, // ENDOOR_SCH_TYPE_HONEY_DARLING_SHOP
/* 27 */ DOOR_OBJINFO_27, // ENDOOR_SCH_TYPE_MILK_BAR
/* 28 */ DOOR_OBJINFO_28, // ENDOOR_SCH_TYPE_INN_MAIN_ENTRANCE
/* 29 */ DOOR_OBJINFO_29, // ENDOOR_SCH_TYPE_INN_UPPER_ENTRANCE
/* 30 */ DOOR_OBJINFO_30, // ENDOOR_SCH_TYPE_INN_GRANNYS
/* 31 */ DOOR_OBJINFO_31, // ENDOOR_SCH_TYPE_INN_STAFF_ROOM
/* 32 */ DOOR_OBJINFO_32, // ENDOOR_SCH_TYPE_INN_KNIFE_CHAMBER
/* 33 */ DOOR_OBJINFO_33, // ENDOOR_SCH_TYPE_INN_LARGE_SUITE
/* 34 */ DOOR_OBJINFO_34, // ENDOOR_SCH_TYPE_MAYORS_RESIDENCE_MAIN_ENTRANCE
/* 35 */ DOOR_OBJINFO_35, // ENDOOR_SCH_TYPE_MAYORS_RESIDENCE_MAYOR_DOTOUR
/* 36 */ DOOR_OBJINFO_36, // ENDOOR_SCH_TYPE_MAYORS_RESIDENCE_MADAME_AROMA
/* 37 */ DOOR_OBJINFO_37, // ENDOOR_SCH_TYPE_MAYORS_RESIDENCE_BEDROOM
/* 38 */ DOOR_OBJINFO_38, // ENDOOR_SCH_TYPE_21
/* 39 */ DOOR_OBJINFO_39, // ENDOOR_SCH_TYPE_ROMANI_RANCH_MAMAS_HOUSE
/* 40 */ DOOR_OBJINFO_40, // ENDOOR_SCH_TYPE_ROMANI_RANCH_BARN
/* 41 */ DOOR_OBJINFO_41, // ENDOOR_SCH_TYPE_ROMANI_RANCH_CUCCO_SHACK
/* 42 */ DOOR_OBJINFO_42, // ENDOOR_SCH_TYPE_ROMANI_RANCH_DOGGY_RACETRACK
/* 43 */ DOOR_OBJINFO_43, // ENDOOR_SCH_TYPE_ROMANI_RANCH_BEDROOM
/* 44 */ DOOR_OBJINFO_44, // ENDOOR_SCH_TYPE_IKANA_CANYON_MUSIC_BOX_HOUSE
/* 45 */ DOOR_OBJINFO_45, // ENDOOR_SCH_TYPE_DAMPES_HOUSE
/* 46 */ DOOR_OBJINFO_46, // ENDOOR_SCH_TYPE_MAGIC_HAGS_POTION_SHOP
/* 47 */ DOOR_OBJINFO_47, // ENDOOR_SCH_TYPE_30
/* 48 */ DOOR_OBJINFO_48, // ENDOOR_SCH_TYPE_SWAMP_SHOOTING_GALLERY
/* 49 */ DOOR_OBJINFO_MAX
} EnDoorObjectInfoIndex;
// These static asserts try to ensure the two enums don't get out of sync
static_assert(ENDOOR_SCH_TYPE_SWORDSMANS_SCHOOL == DOOR_OBJINFO_17 - DOOR_OBJKIND_SCHEDULE,
"The enums values of `EnDoorScheduleType` and `EnDoorObjectInfoIndex` (from `DOOR_OBJKIND_SCHEDULE` "
"onwards) must be synced.");
static_assert(ENDOOR_SCH_TYPE_MAX == DOOR_OBJINFO_MAX - DOOR_OBJKIND_SCHEDULE,
"The enums values of `EnDoorScheduleType` and `EnDoorObjectInfoIndex` (from `DOOR_OBJKIND_SCHEDULE` "
"onwards) must be synced.");
static EnDoorInfo sObjectInfo[] = {
{ SCENE_MITURIN, 0x01, OBJECT_NUMA_OBJ },
{ SCENE_TENMON_DAI, 0x02, OBJECT_DOR01 },
{ SCENE_00KEIKOKU, 0x02, OBJECT_DOR01 },
{ SCENE_30GYOSON, 0x02, OBJECT_DOR01 },
{ SCENE_LABO, 0x02, OBJECT_DOR01 },
{ SCENE_33ZORACITY, 0x03, OBJECT_DOR02 },
{ SCENE_UNSET_31, 0x03, OBJECT_DOR02 },
{ SCENE_BANDROOM, 0x03, OBJECT_DOR02 },
{ SCENE_20SICHITAI, 0x04, OBJECT_DOR03 },
{ SCENE_20SICHITAI2, 0x04, OBJECT_DOR03 },
{ SCENE_MAP_SHOP, 0x04, OBJECT_DOR03 },
{ SCENE_KAIZOKU, 0x0B, OBJECT_KAIZOKU_OBJ },
{ SCENE_PIRATE, 0x0B, OBJECT_KAIZOKU_OBJ },
{ SCENE_TORIDE, 0x0B, OBJECT_KAIZOKU_OBJ },
{ SCENE_KINDAN2, 0x0C, OBJECT_KINSTA2_OBJ },
{ -1, 0x00, GAMEPLAY_KEEP },
{ -1, 0x0D, GAMEPLAY_FIELD_KEEP },
{ -1, 0x08, OBJECT_WDOR03 },
{ -1, 0x07, OBJECT_WDOR02 },
{ -1, 0x06, OBJECT_WDOR01 },
{ -1, 0x07, OBJECT_WDOR02 },
{ -1, 0x06, OBJECT_WDOR01 },
{ -1, 0x00, GAMEPLAY_KEEP },
{ -1, 0x00, GAMEPLAY_KEEP },
{ -1, 0x00, GAMEPLAY_KEEP },
{ -1, 0x00, GAMEPLAY_KEEP },
{ -1, 0x00, GAMEPLAY_KEEP },
{ -1, 0x09, OBJECT_WDOR04 },
{ -1, 0x08, OBJECT_WDOR03 },
{ -1, 0x08, OBJECT_WDOR03 },
{ -1, 0x0D, GAMEPLAY_FIELD_KEEP },
{ -1, 0x0D, GAMEPLAY_FIELD_KEEP },
{ -1, 0x0D, GAMEPLAY_FIELD_KEEP },
{ -1, 0x0D, GAMEPLAY_FIELD_KEEP },
{ -1, 0x06, OBJECT_WDOR01 },
{ -1, 0x00, GAMEPLAY_KEEP },
{ -1, 0x00, GAMEPLAY_KEEP },
{ -1, 0x00, GAMEPLAY_KEEP },
{ -1, 0x00, GAMEPLAY_KEEP },
{ -1, 0x0D, GAMEPLAY_FIELD_KEEP },
{ -1, 0x0D, GAMEPLAY_FIELD_KEEP },
{ -1, 0x0D, GAMEPLAY_FIELD_KEEP },
{ -1, 0x0D, GAMEPLAY_FIELD_KEEP },
{ -1, 0x00, GAMEPLAY_KEEP },
{ -1, 0x0A, OBJECT_WDOR05 },
{ -1, 0x0D, GAMEPLAY_FIELD_KEEP },
{ -1, 0x05, OBJECT_DOR04 },
{ -1, 0x09, OBJECT_WDOR04 },
{ -1, 0x04, OBJECT_DOR03 },
// DOOR_OBJKIND_DEFAULT
{ SCENE_MITURIN, DOOR_DL_WOODFALL, OBJECT_NUMA_OBJ }, // DOOR_OBJINFO_0
{ SCENE_TENMON_DAI, DOOR_DL_OBSERVATORY_LAB, OBJECT_DOR01 }, // DOOR_OBJINFO_1
{ SCENE_00KEIKOKU, DOOR_DL_OBSERVATORY_LAB, OBJECT_DOR01 }, // DOOR_OBJINFO_2
{ SCENE_30GYOSON, DOOR_DL_OBSERVATORY_LAB, OBJECT_DOR01 }, // DOOR_OBJINFO_3
{ SCENE_LABO, DOOR_DL_OBSERVATORY_LAB, OBJECT_DOR01 }, // DOOR_OBJINFO_4
{ SCENE_33ZORACITY, DOOR_DL_ZORA_HALL, OBJECT_DOR02 }, // DOOR_OBJINFO_5
{ SCENE_UNSET_31, DOOR_DL_ZORA_HALL, OBJECT_DOR02 }, // DOOR_OBJINFO_6
{ SCENE_BANDROOM, DOOR_DL_ZORA_HALL, OBJECT_DOR02 }, // DOOR_OBJINFO_7
{ SCENE_20SICHITAI, DOOR_DL_SWAMP, OBJECT_DOR03 }, // DOOR_OBJINFO_8
{ SCENE_20SICHITAI2, DOOR_DL_SWAMP, OBJECT_DOR03 }, // DOOR_OBJINFO_9
{ SCENE_MAP_SHOP, DOOR_DL_SWAMP, OBJECT_DOR03 }, // DOOR_OBJINFO_10
{ SCENE_KAIZOKU, DOOR_DL_PIRATES_FORTESS, OBJECT_KAIZOKU_OBJ }, // DOOR_OBJINFO_11
{ SCENE_PIRATE, DOOR_DL_PIRATES_FORTESS, OBJECT_KAIZOKU_OBJ }, // DOOR_OBJINFO_12
{ SCENE_TORIDE, DOOR_DL_PIRATES_FORTESS, OBJECT_KAIZOKU_OBJ }, // DOOR_OBJINFO_13
{ SCENE_KINDAN2, DOOR_DL_OCEANSIDE_SPIDER_HOUSE, OBJECT_KINSTA2_OBJ }, // DOOR_OBJINFO_14
// DOOR_OBJKIND_KEEP
{ -1, DOOR_DL_DEFAULT, GAMEPLAY_KEEP }, // DOOR_OBJINFO_15
{ -1, DOOR_DL_DEFAULT_FIELD_KEEP, GAMEPLAY_FIELD_KEEP }, // DOOR_OBJINFO_16
// DOOR_OBJKIND_SCHEDULE
{ -1, DOOR_DL_INN_SCHOOL, OBJECT_WDOR03 }, // DOOR_OBJINFO_17
{ -1, DOOR_DL_POST_OFFICE_TRAIDING_POST, OBJECT_WDOR02 }, // DOOR_OBJINFO_18
{ -1, DOOR_DL_LOTTERY_CURIOSITY_SHIP_MAYOR_HOUSE, OBJECT_WDOR01 }, // DOOR_OBJINFO_19
{ -1, DOOR_DL_POST_OFFICE_TRAIDING_POST, OBJECT_WDOR02 }, // DOOR_OBJINFO_20
{ -1, DOOR_DL_LOTTERY_CURIOSITY_SHIP_MAYOR_HOUSE, OBJECT_WDOR01 }, // DOOR_OBJINFO_21
{ -1, DOOR_DL_DEFAULT, GAMEPLAY_KEEP }, // DOOR_OBJINFO_22
{ -1, DOOR_DL_DEFAULT, GAMEPLAY_KEEP }, // DOOR_OBJINFO_23
{ -1, DOOR_DL_DEFAULT, GAMEPLAY_KEEP }, // DOOR_OBJINFO_24
{ -1, DOOR_DL_DEFAULT, GAMEPLAY_KEEP }, // DOOR_OBJINFO_25
{ -1, DOOR_DL_DEFAULT, GAMEPLAY_KEEP }, // DOOR_OBJINFO_26
{ -1, DOOR_DL_MILK_BAR, OBJECT_WDOR04 }, // DOOR_OBJINFO_27
{ -1, DOOR_DL_INN_SCHOOL, OBJECT_WDOR03 }, // DOOR_OBJINFO_28
{ -1, DOOR_DL_INN_SCHOOL, OBJECT_WDOR03 }, // DOOR_OBJINFO_29
{ -1, DOOR_DL_DEFAULT_FIELD_KEEP, GAMEPLAY_FIELD_KEEP }, // DOOR_OBJINFO_30
{ -1, DOOR_DL_DEFAULT_FIELD_KEEP, GAMEPLAY_FIELD_KEEP }, // DOOR_OBJINFO_31
{ -1, DOOR_DL_DEFAULT_FIELD_KEEP, GAMEPLAY_FIELD_KEEP }, // DOOR_OBJINFO_32
{ -1, DOOR_DL_DEFAULT_FIELD_KEEP, GAMEPLAY_FIELD_KEEP }, // DOOR_OBJINFO_33
{ -1, DOOR_DL_LOTTERY_CURIOSITY_SHIP_MAYOR_HOUSE, OBJECT_WDOR01 }, // DOOR_OBJINFO_34
{ -1, DOOR_DL_DEFAULT, GAMEPLAY_KEEP }, // DOOR_OBJINFO_35
{ -1, DOOR_DL_DEFAULT, GAMEPLAY_KEEP }, // DOOR_OBJINFO_36
{ -1, DOOR_DL_DEFAULT, GAMEPLAY_KEEP }, // DOOR_OBJINFO_37
{ -1, DOOR_DL_DEFAULT, GAMEPLAY_KEEP }, // DOOR_OBJINFO_38
{ -1, DOOR_DL_DEFAULT_FIELD_KEEP, GAMEPLAY_FIELD_KEEP }, // DOOR_OBJINFO_39
{ -1, DOOR_DL_DEFAULT_FIELD_KEEP, GAMEPLAY_FIELD_KEEP }, // DOOR_OBJINFO_40
{ -1, DOOR_DL_DEFAULT_FIELD_KEEP, GAMEPLAY_FIELD_KEEP }, // DOOR_OBJINFO_41
{ -1, DOOR_DL_DEFAULT_FIELD_KEEP, GAMEPLAY_FIELD_KEEP }, // DOOR_OBJINFO_42
{ -1, DOOR_DL_DEFAULT, GAMEPLAY_KEEP }, // DOOR_OBJINFO_43
{ -1, DOOR_DL_MUSIC_BOX, OBJECT_WDOR05 }, // DOOR_OBJINFO_44
{ -1, DOOR_DL_DEFAULT_FIELD_KEEP, GAMEPLAY_FIELD_KEEP }, // DOOR_OBJINFO_45
{ -1, DOOR_DL_MAGIC_HAG_POTION_SHOP, OBJECT_DOR04 }, // DOOR_OBJINFO_46
{ -1, DOOR_DL_MILK_BAR, OBJECT_WDOR04 }, // DOOR_OBJINFO_47
{ -1, DOOR_DL_SWAMP, OBJECT_DOR03 }, // DOOR_OBJINFO_48
};
static_assert(ARRAY_COUNT(sObjectInfo) == DOOR_OBJINFO_MAX,
"The entry count of `sObjectInfo` should match the `EnDoorObjectInfoIndex` enum");
static InitChainEntry sInitChain[] = {
ICHAIN_U8(targetMode, TARGET_MODE_0, ICHAIN_CONTINUE),
@ -122,36 +254,41 @@ static InitChainEntry sInitChain[] = {
ICHAIN_U16(shape.rot.z, 0, ICHAIN_STOP),
};
static AnimationHeader* sAnimations[2 * PLAYER_FORM_MAX] = {
static AnimationHeader* sAnimations[] = {
// left
&gameplay_keep_Anim_020658, // PLAYER_FORM_FIERCE_DEITY
&gameplay_keep_Anim_022CA8, // PLAYER_FORM_GORON
&gameplay_keep_Anim_020658, // PLAYER_FORM_ZORA
&gameplay_keep_Anim_022E68, // PLAYER_FORM_DEKU
&gameplay_keep_Anim_0204B4, // PLAYER_FORM_HUMAN
&gDoorFierceDeityZoraOpenLeftAnim, // PLAYER_FORM_FIERCE_DEITY
&gDoorGoronOpenLeftAnim, // PLAYER_FORM_GORON
&gDoorFierceDeityZoraOpenLeftAnim, // PLAYER_FORM_ZORA
&gDoorDekuOpenLeftAnim, // PLAYER_FORM_DEKU
&gDoorHumanOpenLeftAnim, // PLAYER_FORM_HUMAN
// right
&gameplay_keep_Anim_022BE8, // PLAYER_FORM_FIERCE_DEITY
&gameplay_keep_Anim_022D90, // PLAYER_FORM_GORON
&gameplay_keep_Anim_022BE8, // PLAYER_FORM_ZORA
&gameplay_keep_Anim_022FF0, // PLAYER_FORM_DEKU
&gameplay_keep_Anim_0205A0, // PLAYER_FORM_HUMAN
};
static u8 sAnimOpenFrames[2 * PLAYER_FORM_MAX] = {
// left
25, // PLAYER_FORM_FIERCE_DEITY
25, // PLAYER_FORM_GORON
25, // PLAYER_FORM_ZORA
25, // PLAYER_FORM_DEKU
25, // PLAYER_FORM_HUMAN
// right
25, // PLAYER_FORM_FIERCE_DEITY
25, // PLAYER_FORM_GORON
25, // PLAYER_FORM_ZORA
25, // PLAYER_FORM_DEKU
25, // PLAYER_FORM_HUMAN
&gDoorFierceDeityZoraOpenRightAnim, // PLAYER_FORM_FIERCE_DEITY
&gDoorGoronOpenRightAnim, // PLAYER_FORM_GORON
&gDoorFierceDeityZoraOpenRightAnim, // PLAYER_FORM_ZORA
&gDoorDekuOpenRightAnim, // PLAYER_FORM_DEKU
&gDoorHumanOpenRightAnim, // PLAYER_FORM_HUMAN
};
static_assert(ARRAY_COUNT(sAnimations) == 2 * PLAYER_FORM_MAX,
"The entry count of `sAnimations` should be exactly twice as PLAYER_FORM_MAX");
static u8 sAnimCloseFrames[2 * PLAYER_FORM_MAX] = {
static u8 sAnimOpenFrames[] = {
// left
25, // PLAYER_FORM_FIERCE_DEITY
25, // PLAYER_FORM_GORON
25, // PLAYER_FORM_ZORA
25, // PLAYER_FORM_DEKU
25, // PLAYER_FORM_HUMAN
// right
25, // PLAYER_FORM_FIERCE_DEITY
25, // PLAYER_FORM_GORON
25, // PLAYER_FORM_ZORA
25, // PLAYER_FORM_DEKU
25, // PLAYER_FORM_HUMAN
};
static_assert(ARRAY_COUNT(sAnimOpenFrames) == 2 * PLAYER_FORM_MAX,
"The entry count of `sAnimOpenFrames` should be exactly twice as PLAYER_FORM_MAX");
static u8 sAnimCloseFrames[] = {
// left
60, // PLAYER_FORM_FIERCE_DEITY
60, // PLAYER_FORM_GORON
@ -165,23 +302,28 @@ static u8 sAnimCloseFrames[2 * PLAYER_FORM_MAX] = {
60, // PLAYER_FORM_DEKU
70, // PLAYER_FORM_HUMAN
};
static_assert(ARRAY_COUNT(sAnimCloseFrames) == 2 * PLAYER_FORM_MAX,
"The entry count of `sAnimCloseFrames` should be exactly twice as PLAYER_FORM_MAX");
static Gfx* D_808679A4[14][2] = {
{ gDoorLeftDL, gDoorRightDL },
{ gWoodfallDoorDL, gWoodfallDoorDL },
{ gObservatoryLabDoorDL, gObservatoryLabDoorDL },
{ gZoraHallDoorDL, gZoraHallDoorDL },
{ gSwampDoorDL, gSwampDoorDL },
{ gMagicHagPotionShopDoorDL, gMagicHagPotionShopDoorDL },
{ gLotteryCuriosityShopMayorHouseDoorDL, gLotteryCuriosityShopMayorHouseDoorDL },
{ gPostOfficeTradingPostDoorDL, gPostOfficeTradingPostDoorDL },
{ gInnSchoolDoorDL, gInnSchoolDoorDL },
{ gMilkBarDoorDL, gMilkBarDoorDL },
{ gMusicBoxHouseDoorDL, gMusicBoxHouseDoorDL },
{ gPiratesFortressDoorDL, gPiratesFortressDoorDL },
{ gOceansideSpiderHouseDoorDL, gOceansideSpiderHouseDoorDL },
{ gFieldWoodDoorLeftDL, gFieldWoodDoorRightDL },
static Gfx* sDoorDLists[][2] = {
{ gDoorLeftDL, gDoorRightDL }, // DOOR_DL_DEFAULT
{ gWoodfallDoorDL, gWoodfallDoorDL }, // DOOR_DL_WOODFALL
{ gObservatoryLabDoorDL, gObservatoryLabDoorDL }, // DOOR_DL_OBSERVATORY_LAB
{ gZoraHallDoorDL, gZoraHallDoorDL }, // DOOR_DL_ZORA_HALL
{ gSwampDoorDL, gSwampDoorDL }, // DOOR_DL_SWAMP
{ gMagicHagPotionShopDoorDL, gMagicHagPotionShopDoorDL }, // DOOR_DL_MAGIC_HAG_POTION_SHOP
{ gLotteryCuriosityShopMayorHouseDoorDL,
gLotteryCuriosityShopMayorHouseDoorDL }, // DOOR_DL_LOTTERY_CURIOSITY_SHIP_MAYOR_HOUSE
{ gPostOfficeTradingPostDoorDL, gPostOfficeTradingPostDoorDL }, // DOOR_DL_POST_OFFICE_TRAIDING_POST
{ gInnSchoolDoorDL, gInnSchoolDoorDL }, // DOOR_DL_INN_SCHOOL
{ gMilkBarDoorDL, gMilkBarDoorDL }, // DOOR_DL_MILK_BAR
{ gMusicBoxHouseDoorDL, gMusicBoxHouseDoorDL }, // DOOR_DL_MUSIC_BOX
{ gPiratesFortressDoorDL, gPiratesFortressDoorDL }, // DOOR_DL_PIRATES_FORTESS
{ gOceansideSpiderHouseDoorDL, gOceansideSpiderHouseDoorDL }, // DOOR_DL_OCEANSIDE_SPIDER_HOUSE
{ gFieldWoodDoorLeftDL, gFieldWoodDoorRightDL }, // DOOR_DL_DEFAULT_FIELD_KEEP
};
static_assert(ARRAY_COUNT(sDoorDLists) == DOOR_DL_MAX,
"The entry count of `sDoorDLists` should match the `EnDoorDListIndex` enum");
void EnDoor_Init(Actor* thisx, PlayState* play2) {
PlayState* play = play2;
@ -193,165 +335,240 @@ void EnDoor_Init(Actor* thisx, PlayState* play2) {
Actor_ProcessInitChain(&this->knobDoor.dyna.actor, sInitChain);
this->doorType = ENDOOR_GET_TYPE(thisx);
this->typeVar.data = ENDOOR_GET_TYPE_VAR(thisx);
this->switchFlag = ENDOOR_GET_SWITCH_FLAG(thisx);
if ((this->doorType == ENDOOR_TYPE_7) && (this->switchFlag == 0)) {
if ((this->doorType == ENDOOR_TYPE_FRAMED) && (this->typeVar.frameType == ENDOOR_FRAMED_FRAME)) {
DynaPolyActor_Init(&this->knobDoor.dyna, 0);
DynaPolyActor_LoadMesh(play, &this->knobDoor.dyna, &gDoorCol);
DynaPolyActor_LoadMesh(play, &this->knobDoor.dyna, &gFramedDoorCol);
}
SkelAnime_Init(play, &this->knobDoor.skelAnime, &gDoorSkel, &gameplay_keep_Anim_020658, this->limbTable,
SkelAnime_Init(play, &this->knobDoor.skelAnime, &gDoorSkel, &gDoorFierceDeityZoraOpenLeftAnim, this->limbTable,
this->limbTable, DOOR_LIMB_MAX);
if (this->doorType == ENDOOR_TYPE_5) {
objectInfo = &sObjectInfo[17 + this->switchFlag];
if (this->doorType == ENDOOR_TYPE_SCHEDULE) {
objectInfo = &sObjectInfo[DOOR_OBJKIND_SCHEDULE + this->typeVar.schType];
} else {
for (i = 0; i < ARRAY_COUNT(sObjectInfo) - 34; i++, objectInfo++) {
// Look for the EnDoorInfo corresponding to the current scene.
// If no EnDoorInfo matches the current scene then objectInfo will point to the GAMEPLAY_KEEP one
for (i = 0; i < DOOR_OBJKIND_KEEP; i++, objectInfo++) {
if (play->sceneId == objectInfo->sceneId) {
break;
}
}
if ((i >= ARRAY_COUNT(sObjectInfo) - 34) &&
(Object_GetSlot(&play->objectCtx, GAMEPLAY_FIELD_KEEP) > OBJECT_SLOT_NONE)) {
// If objectInfo is pointing to the GAMEPLAY_KEEP's EnDoorInfo one and GAMEPLAY_FIELD_KEEP is loaded then use
// that one instead
if ((i >= DOOR_OBJKIND_KEEP) && (Object_GetSlot(&play->objectCtx, GAMEPLAY_FIELD_KEEP) > OBJECT_SLOT_NONE)) {
objectInfo++;
}
}
// This assignment is redundant since it is set later again
this->knobDoor.dlIndex = objectInfo->dListIndex;
// Check if the object for the selected EnDoorInfo is loaded.
// If it isn't, then fallback to GAMEPLAY_KEEP
objectSlot = Object_GetSlot(&play->objectCtx, objectInfo->objectId);
if (objectSlot <= OBJECT_SLOT_NONE) {
objectInfo = &sObjectInfo[15];
objectInfo = &sObjectInfo[DOOR_OBJINFO_15];
objectSlot = Object_GetSlot(&play->objectCtx, objectInfo->objectId);
if (objectSlot != 0) {
Actor_Kill(&this->knobDoor.dyna.actor);
return;
}
}
this->knobDoor.objectSlot = objectSlot;
this->knobDoor.dlIndex = objectInfo->dListIndex; // Set twice?
this->knobDoor.dlIndex = objectInfo->dListIndex;
// If the object that will be used is the one from the InitVars then call EnDoor_WaitForObject directly since we
// know the object will be loaded before this actor has spawned
if (this->knobDoor.dyna.actor.objectSlot == this->knobDoor.objectSlot) {
func_80866A5C(this, play);
EnDoor_WaitForObject(this, play);
} else {
this->actionFunc = func_80866A5C;
this->actionFunc = EnDoor_WaitForObject;
}
Actor_SetFocus(&this->knobDoor.dyna.actor, 35.0f);
}
void EnDoor_Destroy(Actor* thisx, PlayState* play) {
EnDoor* this = (EnDoor*)thisx;
if (this->doorType != ENDOOR_TYPE_7) {
if (this->doorType != ENDOOR_TYPE_FRAMED) {
TransitionActorEntry* transitionEntry =
&play->doorCtx.transitionActorList[DOOR_GET_TRANSITION_ID(&this->knobDoor.dyna.actor)];
if (transitionEntry->id < 0) {
transitionEntry->id = -transitionEntry->id;
}
} else if (this->switchFlag == 0) {
} else if (this->typeVar.frameType == ENDOOR_FRAMED_FRAME) {
DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->knobDoor.dyna.bgId);
}
}
void func_80866A5C(EnDoor* this, PlayState* play) {
if (Object_IsLoaded(&play->objectCtx, this->knobDoor.objectSlot)) {
this->knobDoor.dyna.actor.objectSlot = this->knobDoor.objectSlot;
this->actionFunc = func_80866B20;
this->knobDoor.dyna.actor.world.rot.y = 0;
if (this->doorType == ENDOOR_TYPE_1) {
if (!Flags_GetSwitch(play, this->switchFlag)) {
this->unk_1A6 = 10;
}
} else if ((this->doorType == ENDOOR_TYPE_4) &&
(Actor_WorldDistXZToActor(&this->knobDoor.dyna.actor, &GET_PLAYER(play)->actor) > 120.0f)) {
this->actionFunc = func_8086704C;
this->knobDoor.dyna.actor.world.rot.y = -0x1800;
void EnDoor_WaitForObject(EnDoor* this, PlayState* play) {
if (!Object_IsLoaded(&play->objectCtx, this->knobDoor.objectSlot)) {
return;
}
this->knobDoor.dyna.actor.objectSlot = this->knobDoor.objectSlot;
this->actionFunc = EnDoor_Idle;
this->knobDoor.dyna.actor.world.rot.y = 0;
if (this->doorType == ENDOOR_TYPE_LOCKED) {
if (!Flags_GetSwitch(play, this->typeVar.switchFlag)) {
this->lockTimer = 10;
}
} else if ((this->doorType == ENDOOR_TYPE_AJAR) &&
(Actor_WorldDistXZToActor(&this->knobDoor.dyna.actor, &GET_PLAYER(play)->actor) >
DOOR_AJAR_SLAM_RANGE)) {
this->actionFunc = EnDoor_AjarWait;
this->knobDoor.dyna.actor.world.rot.y = -0x1800;
}
}
void func_80866B20(EnDoor* this, PlayState* play) {
static s32 D_80867BC0;
// Set to true when the MilkBar door acknowledges player is a member
s32 sDoorIsMilkBarMember;
/**
* Closed door waiting for interaction.
*
* General flow of this function and what is prioritized:
* - Handle opening request from player
* - Handle opening request from schedule actor
* - If not on cs mode:
* - If sDoorIsMilkBarMember or player is near the door and looking at it
* - Set this door as the one Player can interact with
* - If it is a locked door
* - Handle loocked door
* - Otherwise if the door is an AJAR one
* - Display a message saying it won't open
* - Otherwise if ENDOOR_TYPE_WHOLE_DAY? or ENDOOR_TYPE_DAY? or ENDOOR_TYPE_NIGHT?
* - Left the door closed depending on the day/night state expected by the door
* - Otherwise if ENDOOR_TYPE_SCHEDULE
* - Run schedule
* - Possibly not allow to open the door and prompt a message depending on the schedule result.
* - Otherwise if ENDOOR_TYPE_AJAR
* - If player is further than DOOR_AJAR_OPEN_RANGE
* - Play Ajar's open/close loop
*/
void EnDoor_Idle(EnDoor* this, PlayState* play) {
Player* player = GET_PLAYER(play);
// 0x1821: Player is a member of the Milk bar
if (Actor_TalkOfferAccepted(&this->knobDoor.dyna.actor, &play->state) &&
(this->knobDoor.dyna.actor.textId == 0x1821)) {
D_80867BC0 = true;
sDoorIsMilkBarMember = true;
}
if (this->knobDoor.playOpenAnim) {
this->actionFunc = func_80867144;
if (this->knobDoor.requestOpen) {
// Player or an NPC has requested this door to open
this->actionFunc = EnDoor_Open;
Animation_PlayOnceSetSpeed(&this->knobDoor.skelAnime, sAnimations[this->knobDoor.animIndex],
(player->stateFlags1 & PLAYER_STATE1_8000000) ? 0.75f : 1.5f);
if (this->unk_1A6 != 0) {
// If this is a locked door then handle small key counts, sfx and switch flag
if (this->lockTimer != 0) {
DUNGEON_KEY_COUNT(gSaveContext.mapIndex) = DUNGEON_KEY_COUNT(gSaveContext.mapIndex) - 1;
Flags_SetSwitch(play, this->switchFlag);
Flags_SetSwitch(play, this->typeVar.switchFlag);
Actor_PlaySfx(&this->knobDoor.dyna.actor, NA_SE_EV_CHAIN_KEY_UNLOCK);
}
} else if (this->openTimer != 0) {
this->actionFunc = func_80866F94;
// An schedule actor has requested to open this door
this->actionFunc = EnDoor_OpenScheduleActor;
Actor_PlaySfx(&this->knobDoor.dyna.actor, NA_SE_EV_DOOR_OPEN);
} else if (!Player_InCsMode(play)) {
Vec3f playerPosRelToDoor;
// Check if player is near this door and looking at it
Actor_OffsetOfPointInActorCoords(&this->knobDoor.dyna.actor, &playerPosRelToDoor, &player->actor.world.pos);
if (D_80867BC0 || ((fabsf(playerPosRelToDoor.y) < 20.0f) && (fabsf(playerPosRelToDoor.x) < 20.0f) &&
(fabsf(playerPosRelToDoor.z) < 50.0f))) {
if (sDoorIsMilkBarMember || ((fabsf(playerPosRelToDoor.y) < 20.0f) && (fabsf(playerPosRelToDoor.x) < 20.0f) &&
(fabsf(playerPosRelToDoor.z) < 50.0f))) {
s16 yawDiff = player->actor.shape.rot.y - this->knobDoor.dyna.actor.shape.rot.y;
if (playerPosRelToDoor.z > 0.0f) {
yawDiff = (0x8000 - yawDiff);
yawDiff = 0x8000 - yawDiff;
}
if (ABS_ALT(yawDiff) < 0x3000) {
// Set this door as the one Player can interact with
player->doorType = PLAYER_DOORTYPE_HANDLE;
player->doorDirection = playerPosRelToDoor.z >= 0.0f ? 1.0f : -1.0f;
player->doorActor = &this->knobDoor.dyna.actor;
if (this->unk_1A6 != 0) {
if (this->lockTimer != 0) {
if (DUNGEON_KEY_COUNT(gSaveContext.mapIndex) <= 0) {
player->doorType = PLAYER_DOORTYPE_TALKING;
// 0x1802: "Missing small key"
this->knobDoor.dyna.actor.textId = 0x1802;
} else {
player->doorTimer = 10;
}
} else if (this->doorType == ENDOOR_TYPE_4) {
} else if (this->doorType == ENDOOR_TYPE_AJAR) {
player->doorType = PLAYER_DOORTYPE_TALKING;
// 0x1800: "It won't open"
this->knobDoor.dyna.actor.textId = 0x1800;
} else if ((this->doorType == ENDOOR_TYPE_0) || (this->doorType == ENDOOR_TYPE_2) ||
(this->doorType == ENDOOR_TYPE_3)) {
} else if ((this->doorType == ENDOOR_TYPE_WHOLE_DAY) || (this->doorType == ENDOOR_TYPE_DAY) ||
(this->doorType == ENDOOR_TYPE_NIGHT)) {
s32 halfDaysDayBit = (play->actorCtx.halfDaysBit & HALFDAYBIT_DAWNS) >> 1;
s32 halfDaysNightBit = play->actorCtx.halfDaysBit & HALFDAYBIT_NIGHTS;
s16 temp_a2 = D_801AED48[this->switchFlag & 7];
s32 textIdOffset = (this->switchFlag >> 3) & 0xF;
s16 openBit = D_801AED48[ENDOOR_GET_HALFDAYBIT_INDEX_FROM_HALFDAYCHECK(this->typeVar.halfDayCheck)];
s32 textIdOffset = ENDOOR_GET_TEXTOFFSET_FROM_HALFDAYCHECK(this->typeVar.halfDayCheck);
if (((this->doorType == ENDOOR_TYPE_0) && !((halfDaysDayBit | halfDaysNightBit) & temp_a2)) ||
((this->doorType == ENDOOR_TYPE_2) && !(halfDaysNightBit & temp_a2)) ||
((this->doorType == ENDOOR_TYPE_3) && !(halfDaysDayBit & temp_a2))) {
// Check if the door should be closed, and prompt a message if its the case
if (((this->doorType == ENDOOR_TYPE_WHOLE_DAY) &&
!((halfDaysDayBit | halfDaysNightBit) & openBit)) ||
((this->doorType == ENDOOR_TYPE_DAY) && !(halfDaysNightBit & openBit)) ||
((this->doorType == ENDOOR_TYPE_NIGHT) && !(halfDaysDayBit & openBit))) {
//! @bug 0x182D does not exist, and there's no message for like 86 entries
s16 baseTextId = 0x182D;
if (this->doorType == ENDOOR_TYPE_3) {
if (this->doorType == ENDOOR_TYPE_NIGHT) {
// 0x180D to 0x181C: messages indicating certain building are closed at night
baseTextId = 0x180D;
} else if (this->doorType == ENDOOR_TYPE_2) {
} else if (this->doorType == ENDOOR_TYPE_DAY) {
// 0x181D to 0x1820: messages for when Pamela is inside the Music Box house with the door
// closed
baseTextId = 0x181D;
}
player->doorType = PLAYER_DOORTYPE_TALKING;
this->knobDoor.dyna.actor.textId = baseTextId + textIdOffset;
}
} else if ((this->doorType == ENDOOR_TYPE_5) && (playerPosRelToDoor.z > 0.0f)) {
} else if ((this->doorType == ENDOOR_TYPE_SCHEDULE) && (playerPosRelToDoor.z > 0.0f)) {
ScheduleOutput scheduleOutput;
if (Schedule_RunScript(play, D_8086778C[this->switchFlag], &scheduleOutput)) {
if (Schedule_RunScript(play, sDoorSchedules[this->typeVar.schType], &scheduleOutput)) {
this->knobDoor.dyna.actor.textId = scheduleOutput.result + 0x1800;
player->doorType = ((this->knobDoor.dyna.actor.textId == 0x1821) && D_80867BC0)
// 0x1821: Player is a member of the Milk bar
// When player closes this specific message then the door changes to PLAYER_DOORTYPE_PROXIMITY,
// allowing player to open the door without having to press the A button again
player->doorType = ((this->knobDoor.dyna.actor.textId == 0x1821) && sDoorIsMilkBarMember)
? PLAYER_DOORTYPE_PROXIMITY
: PLAYER_DOORTYPE_TALKING;
}
}
func_80122F28(player);
}
} else if ((this->doorType == ENDOOR_TYPE_4) && (this->knobDoor.dyna.actor.xzDistToPlayer > 240.0f)) {
} else if ((this->doorType == ENDOOR_TYPE_AJAR) &&
(this->knobDoor.dyna.actor.xzDistToPlayer > DOOR_AJAR_OPEN_RANGE)) {
Actor_PlaySfx(&this->knobDoor.dyna.actor, NA_SE_EV_DOOR_OPEN);
this->actionFunc = func_80867080;
this->actionFunc = EnDoor_AjarOpen;
}
}
}
void func_80866F94(EnDoor* this, PlayState* play) {
/**
* Handle opening and closing request from an schedule actor.
*
* To trigger this an schedule actor must set the `openTimer` member, where its magnitude specifies for how many frames
* the door will be open (after the opening animation) and its sign indicates which direction the door will open. When
* the specified amount of frames has passed the door will closed automatically, without needing intervention from the
* schedule actor.
*/
void EnDoor_OpenScheduleActor(EnDoor* this, PlayState* play) {
s32 direction;
if (this->openTimer != 0) {
@ -365,41 +582,41 @@ void func_80866F94(EnDoor* this, PlayState* play) {
}
} else {
if (Math_ScaledStepToS(&this->knobDoor.dyna.actor.world.rot.y, 0, 0x7D0)) {
this->actionFunc = func_80866B20;
this->actionFunc = EnDoor_Idle;
Actor_PlaySfx(&this->knobDoor.dyna.actor, NA_SE_EV_AUTO_DOOR_CLOSE);
}
}
}
void func_8086704C(EnDoor* this, PlayState* play) {
if (this->knobDoor.dyna.actor.xzDistToPlayer < 120.0f) {
this->actionFunc = func_808670F0;
void EnDoor_AjarWait(EnDoor* this, PlayState* play) {
if (this->knobDoor.dyna.actor.xzDistToPlayer < DOOR_AJAR_SLAM_RANGE) {
this->actionFunc = EnDoor_AjarClose;
}
}
void func_80867080(EnDoor* this, PlayState* play) {
if (this->knobDoor.dyna.actor.xzDistToPlayer < 120.0f) {
this->actionFunc = func_808670F0;
void EnDoor_AjarOpen(EnDoor* this, PlayState* play) {
if (this->knobDoor.dyna.actor.xzDistToPlayer < DOOR_AJAR_SLAM_RANGE) {
this->actionFunc = EnDoor_AjarClose;
} else if (Math_ScaledStepToS(&this->knobDoor.dyna.actor.world.rot.y, -0x1800, 0x100)) {
this->actionFunc = func_8086704C;
this->actionFunc = EnDoor_AjarWait;
}
}
void func_808670F0(EnDoor* this, PlayState* play) {
void EnDoor_AjarClose(EnDoor* this, PlayState* play) {
if (Math_ScaledStepToS(&this->knobDoor.dyna.actor.world.rot.y, 0, 0x700)) {
Actor_PlaySfx(&this->knobDoor.dyna.actor, NA_SE_EV_DOOR_CLOSE);
this->actionFunc = func_80866B20;
this->actionFunc = EnDoor_Idle;
}
}
void func_80867144(EnDoor* this, PlayState* play) {
void EnDoor_Open(EnDoor* this, PlayState* play) {
s32 numEffects;
s32 i;
if (DECR(this->unk_1A6) == 0) {
if (DECR(this->lockTimer) == 0) {
if (SkelAnime_Update(&this->knobDoor.skelAnime)) {
this->actionFunc = func_80866B20;
this->knobDoor.playOpenAnim = false;
this->actionFunc = EnDoor_Idle;
this->knobDoor.requestOpen = false;
} else if (Animation_OnFrame(&this->knobDoor.skelAnime, sAnimOpenFrames[this->knobDoor.animIndex])) {
Actor_PlaySfx(&this->knobDoor.dyna.actor, NA_SE_OC_DOOR_OPEN);
if (this->knobDoor.skelAnime.playSpeed < 1.5f) {
@ -425,22 +642,21 @@ s32 EnDoor_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f*
EnDoor* this = THIS;
if (limbIndex == DOOR_LIMB_4) {
Gfx** sideDLists = D_808679A4[this->knobDoor.dlIndex];
Gfx** sideDLists = sDoorDLists[this->knobDoor.dlIndex];
transitionEntry = NULL;
if (this->doorType != ENDOOR_TYPE_7) {
if (this->doorType != ENDOOR_TYPE_FRAMED) {
transitionEntry = &play->doorCtx.transitionActorList[DOOR_GET_TRANSITION_ID(&this->knobDoor.dyna.actor)];
}
rot->z += this->knobDoor.dyna.actor.world.rot.y;
if ((this->doorType == ENDOOR_TYPE_7) || (play->roomCtx.prevRoom.num >= 0) ||
if ((this->doorType == ENDOOR_TYPE_FRAMED) || (play->roomCtx.prevRoom.num >= 0) ||
(transitionEntry->sides[0].room == transitionEntry->sides[1].room)) {
s16 temp =
(this->knobDoor.dyna.actor.shape.rot.y + this->knobDoor.skelAnime.jointTable[DOOR_LIMB_3].z + rot->z) -
Math_Vec3f_Yaw(&play->view.eye, &this->knobDoor.dyna.actor.world.pos);
*dList = (ABS_ALT(temp) < 0x4000) ? sideDLists[0] : sideDLists[1];
} else {
s32 index = 0;
@ -450,22 +666,26 @@ s32 EnDoor_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f*
*dList = sideDLists[index];
}
}
return false;
}
void EnDoor_Draw(Actor* thisx, PlayState* play) {
EnDoor* this = THIS;
// Ensure the object that will be used is loaded
if (this->knobDoor.dyna.actor.objectSlot == this->knobDoor.objectSlot) {
OPEN_DISPS(play->state.gfxCtx);
if ((this->doorType == ENDOOR_TYPE_7) && (this->switchFlag == 0)) {
if ((this->doorType == ENDOOR_TYPE_FRAMED) && (this->typeVar.frameType == ENDOOR_FRAMED_FRAME)) {
Gfx_DrawDListOpa(play, gameplay_keep_DL_0221B8);
} else {
Gfx_SetupDL25_Opa(play->state.gfxCtx);
}
SkelAnime_DrawOpa(play, this->knobDoor.skelAnime.skeleton, this->knobDoor.skelAnime.jointTable,
EnDoor_OverrideLimbDraw, NULL, &this->knobDoor.dyna.actor);
if (this->knobDoor.dyna.actor.world.rot.y != 0) {
if (this->knobDoor.dyna.actor.world.rot.y > 0) {
gSPDisplayList(POLY_OPA_DISP++, gDoorRightDL);
@ -473,8 +693,8 @@ void EnDoor_Draw(Actor* thisx, PlayState* play) {
gSPDisplayList(POLY_OPA_DISP++, gDoorLeftDL);
}
}
if (this->unk_1A6) {
Actor_DrawDoorLock(play, this->unk_1A6, 0);
if (this->lockTimer) {
Actor_DrawDoorLock(play, this->lockTimer, DOORLOCK_NORMAL);
}
CLOSE_DISPS(play->state.gfxCtx);

View File

@ -5,30 +5,126 @@
#include "z64door.h"
#include "objects/gameplay_keep/gameplay_keep.h"
/**
* Actor Parameters
*
* | | |
* | Transition Index | Type | Type var
* |------------------|-------|---------------
* | 0 0 0 0 0 0 | 0 0 0 | 0 0 0 0 0 0 0
* | 6 | 3 | 7
* |
*
* Transition Index 1111110000000000 Set by the actor engine when the door is spawned (See Actor_SpawnTransitionActors and DOOR_GET_TRANSITION_ID)
* Type 0000001110000000 Values of the EnDoorType enum
* Type var 0000000001111111 Generic extra parameter. It is used differently by each door Type (or not used at all)
*
*
* If type is either ENDOOR_TYPE_WHOLE_DAY, ENDOOR_TYPE_DAY or ENDOOR_TYPE_NIGHT then the Type var is bitpacked like this:
*
* | |
* | Text offset | Half day bit index
* |-------------|--------------------
* | 0 0 0 0 | 0 0 0
* | 4 | 3
* |
*
* Text offset 0000000001111000 Used as an offset relative to a base text id. The base text id is different depending on the door type.
* Half day bit index 0000000000000111 Index into the D_801AED48 array
*
*
* The rest of the door types either don't use the actionv var or don't bitpack extra parameters on it (using the full 7 bits)
*/
struct EnDoor;
typedef void (*EnDoorActionFunc)(struct EnDoor*, PlayState*);
#define ENDOOR_GET_TYPE(thisx) (((thisx)->params >> 7) & 7)
#define ENDOOR_GET_SWITCH_FLAG(thisx) (((thisx)->params) & 0x7F)
typedef enum EnDoorType {
/* 0 */ ENDOOR_TYPE_0,
/* 1 */ ENDOOR_TYPE_1,
/* 2 */ ENDOOR_TYPE_2,
/* 3 */ ENDOOR_TYPE_3,
/* 4 */ ENDOOR_TYPE_4,
/* 5 */ ENDOOR_TYPE_5,
/* 6 */ ENDOOR_TYPE_6,
/* 7 */ ENDOOR_TYPE_7
/* 0 */ ENDOOR_TYPE_WHOLE_DAY, // Allows to specify the door may be closed for full specific days. Which days the door is closed is controlled by the "half day bit index" part of the parameter
/* 1 */ ENDOOR_TYPE_LOCKED,
/* 2 */ ENDOOR_TYPE_DAY, // Allows to specify the door may be closed for specific dawns. Which dawns the door is closed is controlled by the "half day bit index" part of the parameter
/* 3 */ ENDOOR_TYPE_NIGHT, // Allows to specify the door may be closed for specific nights. Which nights the door is closed is controlled by the "half day bit index" part of the parameter
/* 4 */ ENDOOR_TYPE_AJAR, // unused
/* 5 */ ENDOOR_TYPE_SCHEDULE,
/* 6 */ ENDOOR_TYPE_6, // unreferenced
/* 7 */ ENDOOR_TYPE_FRAMED // unused
} EnDoorType;
typedef enum EnDoorScheduleType {
/* 0 */ ENDOOR_SCH_TYPE_SWORDSMANS_SCHOOL,
/* 1 */ ENDOOR_SCH_TYPE_POST_OFFICE,
/* 2 */ ENDOOR_SCH_TYPE_LOTTERY_SHOP,
/* 3 */ ENDOOR_SCH_TYPE_TRADING_POST,
/* 4 */ ENDOOR_SCH_TYPE_CURIOSITY_SHOP,
/* 5 */ ENDOOR_SCH_TYPE_LAUNDRY_POOL,
/* 6 */ ENDOOR_SCH_TYPE_BOMB_SHOP,
/* 7 */ ENDOOR_SCH_TYPE_TOWN_SHOOTING_GALLERY,
/* 8 */ ENDOOR_SCH_TYPE_TREASURE_CHEST_SHOP,
/* 9 */ ENDOOR_SCH_TYPE_HONEY_DARLING_SHOP,
/* 10 */ ENDOOR_SCH_TYPE_MILK_BAR,
/* 11 */ ENDOOR_SCH_TYPE_INN_MAIN_ENTRANCE,
/* 12 */ ENDOOR_SCH_TYPE_INN_UPPER_ENTRANCE,
/* 13 */ ENDOOR_SCH_TYPE_INN_GRANNYS,
/* 14 */ ENDOOR_SCH_TYPE_INN_STAFF_ROOM,
/* 15 */ ENDOOR_SCH_TYPE_INN_KNIFE_CHAMBER,
/* 16 */ ENDOOR_SCH_TYPE_INN_LARGE_SUITE,
/* 17 */ ENDOOR_SCH_TYPE_MAYORS_RESIDENCE_MAIN_ENTRANCE,
/* 18 */ ENDOOR_SCH_TYPE_MAYORS_RESIDENCE_MAYOR_DOTOUR,
/* 19 */ ENDOOR_SCH_TYPE_MAYORS_RESIDENCE_MADAME_AROMA,
/* 20 */ ENDOOR_SCH_TYPE_MAYORS_RESIDENCE_BEDROOM,
/* 21 */ ENDOOR_SCH_TYPE_21, // unused
/* 22 */ ENDOOR_SCH_TYPE_ROMANI_RANCH_MAMAS_HOUSE,
/* 23 */ ENDOOR_SCH_TYPE_ROMANI_RANCH_BARN,
/* 24 */ ENDOOR_SCH_TYPE_ROMANI_RANCH_CUCCO_SHACK,
/* 25 */ ENDOOR_SCH_TYPE_ROMANI_RANCH_DOGGY_RACETRACK,
/* 26 */ ENDOOR_SCH_TYPE_ROMANI_RANCH_BEDROOM,
/* 27 */ ENDOOR_SCH_TYPE_IKANA_CANYON_MUSIC_BOX_HOUSE,
/* 28 */ ENDOOR_SCH_TYPE_DAMPES_HOUSE,
/* 29 */ ENDOOR_SCH_TYPE_MAGIC_HAGS_POTION_SHOP,
/* 30 */ ENDOOR_SCH_TYPE_30, // unused
/* 31 */ ENDOOR_SCH_TYPE_SWAMP_SHOOTING_GALLERY,
/* 32 */ ENDOOR_SCH_TYPE_MAX
} EnDoorScheduleType;
typedef enum EnDoorFramedType {
/* 0 */ ENDOOR_FRAMED_FRAME,
/* 1 */ ENDOOR_FRAMED_NOFRAME
} EnDoorFramedType;
#define ENDOOR_GET_TYPE(thisx) (((thisx)->params >> 7) & 7)
#define ENDOOR_GET_TYPE_VAR(thisx) (((thisx)->params) & 0x7F)
// TODO: rename after D_801AED48
#define ENDOOR_GET_HALFDAYBIT_INDEX_FROM_HALFDAYCHECK(typeVar) ((typeVar) & 0x7)
#define ENDOOR_GET_TEXTOFFSET_FROM_HALFDAYCHECK(typeVar) (((typeVar) >> 3) & 0xF)
#define ENDOOR_PACK_HALFDAYCHECK(halfDayBitIndex, textOffset) ((((textOffset) & 0xF) << 3) | ((halfDayBitIndex) & 0x7))
#define ENDOOR_PARAMS(type, typeVar) ((((type) & 7) << 7) | ((typeVar) & 0x7F))
/**
* `scheduleType` must be a value of the `EnDoorScheduleType` enum
*/
#define ENDOOR_PARAMS_SCHEDULE(scheduleType) ENDOOR_PARAMS(ENDOOR_TYPE_SCHEDULE, scheduleType)
/**
* `scheduleType` must be a value of the `EnDoorFramedType` enum
*/
#define ENDOOR_PARAMS_FRAMED(frameType) ENDOOR_PARAMS(ENDOOR_TYPE_FRAMED, frameType)
typedef struct EnDoor {
/* 0x000 */ KnobDoorActor knobDoor;
/* 0x1A4 */ u8 doorType; // EnDoorType enum
/* 0x1A5 */ u8 switchFlag;
/* 0x1A6 */ u8 unk_1A6;
/* 0x1A7 */ s8 openTimer; // For how long the door will be open. positive/negative means the opening direction
/* 0x1A5 */ union {
u8 data; // generic
u8 halfDayCheck; // ENDOOR_TYPE_WHOLE_DAY, ENDOOR_TYPE_DAY and ENDOOR_TYPE_NIGHT
u8 switchFlag; // ENDOOR_TYPE_LOCKED
u8 schType; // ENDOOR_TYPE_SCHEDULE
u8 frameType; // ENDOOR_TYPE_FRAMED
} typeVar;
/* 0x1A6 */ u8 lockTimer; // Used by ENDOOR_TYPE_LOCKED. Also controls drawing the lock on the door and side effects of opening a locked door, like decreasing the key count and updating the switch flag
/* 0x1A7 */ s8 openTimer; // For how long the door will be open. positive/negative means the opening direction. It is meant to be used only by ENDOOR_TYPE_SCHEDULE, and set by schedule actors. See EnDoor_OpenScheduleActor.
/* 0x1A8 */ Vec3s limbTable[DOOR_LIMB_MAX];
/* 0x1C8 */ EnDoorActionFunc actionFunc;
} EnDoor;

View File

@ -176,7 +176,7 @@ void func_80AC21A0(EnDoorEtc* this, PlayState* play) {
s32 yawDiffAbs;
Actor_OffsetOfPointInActorCoords(&this->knobDoor.dyna.actor, &playerOffsetFromDoor, &player->actor.world.pos);
if (!this->knobDoor.playOpenAnim) {
if (!this->knobDoor.requestOpen) {
if ((!Player_InCsMode(play)) &&
((fabsf(playerOffsetFromDoor.y) < 20.0f) && fabsf(playerOffsetFromDoor.x) < 20.0f) &&
(fabsf(playerOffsetFromDoor.z) < 50.0f)) {

View File

@ -171,39 +171,40 @@ Actor* EnGm_FindActor(EnGm* this, PlayState* play, u8 actorCategory, s16 actorId
return actorIter;
}
EnDoor* func_8094DF90(PlayState* play, s32 arg1) {
s32 phi_a1;
EnDoor* EnGm_FindScheduleDoor(PlayState* play, s32 scheduleOutputResult) {
EnDoorScheduleType schType;
switch (arg1) {
switch (scheduleOutputResult) {
case 9:
case 13:
case 15:
phi_a1 = 11;
schType = ENDOOR_SCH_TYPE_INN_MAIN_ENTRANCE;
break;
case 10:
case 11:
case 16:
case 17:
phi_a1 = 17;
schType = ENDOOR_SCH_TYPE_MAYORS_RESIDENCE_MAIN_ENTRANCE;
break;
case 12:
case 14:
case 20:
phi_a1 = 10;
schType = ENDOOR_SCH_TYPE_MILK_BAR;
break;
case 18:
case 19:
phi_a1 = 19;
schType = ENDOOR_SCH_TYPE_MAYORS_RESIDENCE_MADAME_AROMA;
break;
default:
phi_a1 = -1;
schType = -1;
break;
}
return SubS_FindDoor(play, phi_a1);
return SubS_FindScheduleDoor(play, schType);
}
s32 EnGm_UpdateSkelAnime(EnGm* this, PlayState* play) {
@ -942,7 +943,7 @@ s32 func_8094F904(EnGm* this, PlayState* play, ScheduleOutput* scheduleOutput) {
s32 ret = false;
this->timePath = NULL;
door = func_8094DF90(play, scheduleOutput->result);
door = EnGm_FindScheduleDoor(play, scheduleOutput->result);
if (D_80951A0C[scheduleOutput->result] >= 0) {
this->timePath = SubS_GetAdditionalPath(play, pathIndex, D_80951A0C[scheduleOutput->result]);
@ -1379,7 +1380,7 @@ s32 func_80950804(EnGm* this, PlayState* play) {
s32 pad;
f32 temp_f0;
door = func_8094DF90(play, this->unk_258);
door = EnGm_FindScheduleDoor(play, this->unk_258);
if (!SubS_InCsMode(play) && (this->timePathTimeSpeed != 0)) {
if ((door != NULL) && (door->knobDoor.dyna.actor.update != NULL)) {
if ((this->unk_3BA / (f32)this->unk_3B8) <= 0.9f) {

View File

@ -156,26 +156,27 @@ Actor* EnIg_FindActor(EnIg* this, PlayState* play, u8 actorCategory, s16 actorId
return actorIter;
}
EnDoor* func_80BF1200(PlayState* play, s32 arg1) {
s32 phi_a1;
EnDoor* EnIg_FindScheduleDoor(PlayState* play, s32 scheduleOutputResult) {
EnDoorScheduleType schType;
switch (arg1) {
switch (scheduleOutputResult) {
case 5:
case 6:
case 7:
case 9:
phi_a1 = 11;
schType = ENDOOR_SCH_TYPE_INN_MAIN_ENTRANCE;
break;
case 8:
phi_a1 = 15;
schType = ENDOOR_SCH_TYPE_INN_KNIFE_CHAMBER;
break;
default:
phi_a1 = -1;
schType = -1;
break;
}
return SubS_FindDoor(play, phi_a1);
return SubS_FindScheduleDoor(play, schType);
}
void EnIg_UpdateSkelAnime(EnIg* this) {
@ -534,7 +535,7 @@ s32 func_80BF1DF4(EnIg* this, PlayState* play, ScheduleOutput* scheduleOutput) {
s32 ret = false;
this->timePath = NULL;
door = func_80BF1200(play, scheduleOutput->result);
door = EnIg_FindScheduleDoor(play, scheduleOutput->result);
if (D_80BF3318[scheduleOutput->result] >= 0) {
this->timePath = SubS_GetAdditionalPath(play, pathIndex, D_80BF3318[scheduleOutput->result]);
@ -719,7 +720,7 @@ s32 func_80BF2400(EnIg* this, PlayState* play) {
}
s32 func_80BF2470(EnIg* this, PlayState* play) {
EnDoor* door = func_80BF1200(play, this->scheduleResult);
EnDoor* door = EnIg_FindScheduleDoor(play, this->scheduleResult);
Vec3f sp38;
f32 temp;
s32 pad;

View File

@ -263,36 +263,36 @@ Actor* EnPm_FindActor(EnPm* this, PlayState* play, u8 actorCategory, s16 actorId
return actorIter;
}
EnDoor* func_80AF7D60(PlayState* play, s32 arg1) {
s32 phi_a1;
EnDoor* EnPm_FindScheduleDoor(PlayState* play, s32 scheduleOutputResult) {
EnDoorScheduleType schType;
switch (arg1) {
switch (scheduleOutputResult) {
case 1:
case 2:
case 32:
case 33:
phi_a1 = 1;
schType = ENDOOR_SCH_TYPE_POST_OFFICE;
break;
case 34:
case 35:
case 36:
case 37:
phi_a1 = 10;
schType = ENDOOR_SCH_TYPE_MILK_BAR;
break;
case 10:
case 11:
case 12:
case 13:
phi_a1 = 11;
schType = ENDOOR_SCH_TYPE_INN_MAIN_ENTRANCE;
break;
default:
return NULL;
}
return SubS_FindDoor(play, phi_a1);
return SubS_FindScheduleDoor(play, schType);
}
Actor* func_80AF7DC4(EnPm* this, PlayState* play, s32 arg2) {
@ -877,7 +877,7 @@ s32 func_80AF9008(EnPm* this, PlayState* play, ScheduleOutput* scheduleOutput) {
s32 ret = false;
this->timePath = NULL;
door = func_80AF7D60(play, scheduleOutput->result);
door = EnPm_FindScheduleDoor(play, scheduleOutput->result);
if (D_80AFB430[scheduleOutput->result] >= 0) {
this->timePath = SubS_GetAdditionalPath(play, pathIndex, D_80AFB430[scheduleOutput->result]);
}
@ -1338,7 +1338,7 @@ s32 func_80AF9BF8(EnPm* this, PlayState* play, ScheduleOutput* scheduleOutput) {
}
s32 func_80AF9D04(EnPm* this, PlayState* play) {
EnDoor* door = (EnDoor*)func_80AF7D60(play, this->unk_258);
EnDoor* door = EnPm_FindScheduleDoor(play, this->unk_258);
Vec3f sp38;
s32 pad;
f32 temp;

View File

@ -717,7 +717,7 @@ s32 func_80BABC48(EnSuttari* this, PlayState* play, ScheduleOutput* scheduleOutp
s32 func_80BABDD8(EnSuttari* this, PlayState* play, ScheduleOutput* scheduleOutput) {
s32 pad;
EnDoor* sp48;
EnDoor* door;
u8 pathIndex = ENSUTTARI_GET_PATH_INDEX(&this->actor);
u16 sp44 = SCHEDULE_TIME_NOW;
Vec3f sp38;
@ -728,12 +728,12 @@ s32 func_80BABDD8(EnSuttari* this, PlayState* play, ScheduleOutput* scheduleOutp
if ((this->unk428 == 10) || (this->unk428 == 11) || (this->unk428 == 2)) {
return false;
}
sp48 = (EnDoor*)SubS_FindNearestActor(&this->actor, play, ACTORCAT_DOOR, ACTOR_EN_DOOR);
door = (EnDoor*)SubS_FindNearestActor(&this->actor, play, ACTORCAT_DOOR, ACTOR_EN_DOOR);
sp24 = D_80BAE8F8[scheduleOutput->result];
if ((sp48 != NULL) && (sp24 >= 0)) {
if ((door != NULL) && (sp24 >= 0)) {
this->timePath = SubS_GetAdditionalPath(play, pathIndex, sp24);
}
if ((sp48 == NULL) || (this->timePath == NULL)) {
if ((door == NULL) || (this->timePath == NULL)) {
return false;
}
sp28 = Lib_SegmentedToVirtual(this->timePath->points);
@ -742,7 +742,7 @@ s32 func_80BABDD8(EnSuttari* this, PlayState* play, ScheduleOutput* scheduleOutp
this->unk434 = sp44 - scheduleOutput->time0;
this->unk436 = scheduleOutput->time1 - scheduleOutput->time0;
if ((scheduleOutput->result != 10) && (scheduleOutput->result != 11)) {
sp48->openTimer = 75;
door->openTimer = 75;
}
Math_Vec3f_Copy(&this->unk438, &sp38);
Math_Vec3f_Copy(&this->unk444, &sp2C);

View File

@ -518,7 +518,7 @@ s32 func_80A3F384(EnTest3* this, PlayState* play) {
EnDoor* door = (EnDoor*)func_80A3F2BC(play, this, ACTOR_EN_DOOR, ACTORCAT_DOOR, 55.0f, 20.0f);
Vec3f offset;
if ((door != NULL) && !door->knobDoor.playOpenAnim &&
if ((door != NULL) && !door->knobDoor.requestOpen &&
((player->doorType == PLAYER_DOORTYPE_NONE) || (&door->knobDoor.dyna.actor != player->doorActor)) &&
Actor_ActorAIsFacingActorB(&this->player.actor, &door->knobDoor.dyna.actor, 0x3000)) {
Actor_OffsetOfPointInActorCoords(&door->knobDoor.dyna.actor, &offset, &this->player.actor.world.pos);

View File

@ -6456,12 +6456,12 @@ void Player_Door_Knob(PlayState* play, Player* this, Actor* door) {
func_8082DAD4(this);
Player_AnimReplace_Setup(
play, this, ANIM_FLAG_1 | ANIM_FLAG_UPDATE_Y | ANIM_FLAG_4 | ANIM_FLAG_8 | ANIM_FLAG_80 | ANIM_FLAG_200);
knobDoor->playOpenAnim = true;
knobDoor->requestOpen = true;
if (this->doorType != PLAYER_DOORTYPE_FAKE) {
CollisionPoly* poly;
s32 bgId;
Vec3f pos;
s32 enDoorType = ENDOOR_GET_TYPE(&knobDoor->dyna.actor);
EnDoorType enDoorType = ENDOOR_GET_TYPE(&knobDoor->dyna.actor);
this->stateFlags1 |= PLAYER_STATE1_20000000;
@ -6473,7 +6473,7 @@ void Player_Door_Knob(PlayState* play, Player* this, Actor* door) {
if (Player_HandleExitsAndVoids(play, this, poly, BGCHECK_SCENE)) {
gSaveContext.entranceSpeed = 2.0f;
} else if (enDoorType != ENDOOR_TYPE_7) {
} else if (enDoorType != ENDOOR_TYPE_FRAMED) {
Camera* mainCam;
this->av1.actionVar1 = 38.0f * D_8085C3E8;
@ -6526,7 +6526,8 @@ s32 Player_ActionChange_1(Player* this, PlayState* play) {
if (this->actor.category == ACTORCAT_PLAYER) {
if ((this->doorType < PLAYER_DOORTYPE_FAKE) && (doorActor->category == ACTORCAT_DOOR) &&
((this->doorType != PLAYER_DOORTYPE_HANDLE) || (ENDOOR_GET_TYPE(doorActor) != ENDOOR_TYPE_7))) {
((this->doorType != PLAYER_DOORTYPE_HANDLE) ||
(ENDOOR_GET_TYPE(doorActor) != ENDOOR_TYPE_FRAMED))) {
s8 roomNum = play->doorCtx.transitionActorList[DOOR_GET_TRANSITION_ID(doorActor)]
.sides[(this->doorDirection > 0) ? 0 : 1]
.room;
@ -15308,7 +15309,7 @@ void Player_Action_35(Player* this, PlayState* play) {
// door stuff
void Player_Action_36(Player* this, PlayState* play) {
EnDoor* doorActor = (EnDoor*)this->doorActor;
s32 sp38 = (doorActor != NULL) && (doorActor->doorType == ENDOOR_TYPE_7);
s32 framedDoor = (doorActor != NULL) && (doorActor->doorType == ENDOOR_TYPE_FRAMED);
s32 animFinished;
CollisionPoly* poly;
s32 bgId;
@ -15332,7 +15333,7 @@ void Player_Action_36(Player* this, PlayState* play) {
Player_StopCutscene(this);
func_80839E74(this, play);
if ((this->actor.category == ACTORCAT_PLAYER) && !sp38) {
if ((this->actor.category == ACTORCAT_PLAYER) && !framedDoor) {
if (play->roomCtx.prevRoom.num >= 0) {
func_8012EBF8(play, &play->roomCtx);
}
@ -15344,7 +15345,7 @@ void Player_Action_36(Player* this, PlayState* play) {
} else if (!(this->stateFlags1 & PLAYER_STATE1_20000000) && PlayerAnimation_OnFrame(&this->skelAnime, 15.0f)) {
Player_StopCutscene(this);
play->func_18780(this, play);
} else if (sp38 && PlayerAnimation_OnFrame(&this->skelAnime, 15.0f)) {
} else if (framedDoor && PlayerAnimation_OnFrame(&this->skelAnime, 15.0f)) {
s16 exitIndexPlusOne = (this->doorDirection < 0) ? doorActor->knobDoor.dyna.actor.world.rot.x
: doorActor->knobDoor.dyna.actor.world.rot.z;

View File

@ -2655,7 +2655,7 @@
0x8013A4C4:("Snap_CheckFlag",),
0x8013A504:("Snap_AbsS",),
0x8013A530:("Snap_ValidatePictograph",),
0x8013A7C0:("SubS_FindDoor",),
0x8013A7C0:("SubS_FindScheduleDoor",),
0x8013A860:("SubS_DrawTransformFlexLimb",),
0x8013AB00:("SubS_DrawTransformFlex",),
0x8013AD6C:("SubS_InCsMode",),
@ -4952,13 +4952,13 @@
0x80866398:("EnLight_Draw",),
0x80866800:("EnDoor_Init",),
0x808669E0:("EnDoor_Destroy",),
0x80866A5C:("func_80866A5C",),
0x80866B20:("func_80866B20",),
0x80866F94:("func_80866F94",),
0x8086704C:("func_8086704C",),
0x80867080:("func_80867080",),
0x808670F0:("func_808670F0",),
0x80867144:("func_80867144",),
0x80866A5C:("EnDoor_WaitForObject",),
0x80866B20:("EnDoor_Idle",),
0x80866F94:("EnDoor_OpenScheduleActor",),
0x8086704C:("EnDoor_AjarWait",),
0x80867080:("EnDoor_AjarOpen",),
0x808670F0:("EnDoor_AjarClose",),
0x80867144:("EnDoor_Open",),
0x8086732C:("EnDoor_Update",),
0x80867350:("EnDoor_OverrideLimbDraw",),
0x808674B0:("EnDoor_Draw",),
@ -7579,7 +7579,7 @@
0x809495F8:("EnClearTag_UpdateEffects",),
0x80949BD4:("EnClearTag_DrawEffects",),
0x8094DEE0:("EnGm_FindActor",),
0x8094DF90:("func_8094DF90",),
0x8094DF90:("EnGm_FindScheduleDoor",),
0x8094DFF8:("EnGm_UpdateSkelAnime",),
0x8094E054:("EnGm_ChangeAnim",),
0x8094E0F8:("func_8094E0F8",),
@ -12729,7 +12729,7 @@
0x80AF7B40:("func_80AF7B40",),
0x80AF7BAC:("func_80AF7BAC",),
0x80AF7CB0:("EnPm_FindActor",),
0x80AF7D60:("func_80AF7D60",),
0x80AF7D60:("EnPm_FindScheduleDoor",),
0x80AF7DC4:("func_80AF7DC4",),
0x80AF7E6C:("func_80AF7E6C",),
0x80AF7E98:("func_80AF7E98",),
@ -14010,7 +14010,7 @@
0x80B53840:("EnAn_InitObjectSlots",),
0x80B539CC:("EnAn_FindActor",),
0x80B53A7C:("func_80B53A7C",),
0x80B53B3C:("EnAn_FindDoor",),
0x80B53B3C:("EnAn_FindScheduleDoor",),
0x80B53BA8:("EnAn_UpdateSkelAnime",),
0x80B53CE8:("EnAn_ChangeAnim",),
0x80B53ED4:("EnAn_UpdateCollider",),
@ -16282,7 +16282,7 @@
0x80BF0EEC:("EffStk_Update",),
0x80BF0F10:("EffStk_Draw",),
0x80BF1150:("EnIg_FindActor",),
0x80BF1200:("func_80BF1200",),
0x80BF1200:("EnIg_FindActor",),
0x80BF1258:("EnIg_UpdateSkelAnime",),
0x80BF1284:("EnIg_ChangeAnim",),
0x80BF1354:("func_80BF1354",),

View File

@ -5357,48 +5357,48 @@
0x8086675C:("D_8086675C","f32","",0x4),
0x80866760:("D_80866760","f32","",0x4),
0x80866764:("D_80866764","f32","",0x4),
0x808675D0:("D_808675D0","UNK_TYPE1","",0x1),
0x808675E4:("D_808675E4","UNK_TYPE1","",0x1),
0x80867634:("D_80867634","UNK_TYPE1","",0x1),
0x80867640:("D_80867640","UNK_TYPE1","",0x1),
0x8086764C:("D_8086764C","UNK_TYPE1","",0x1),
0x80867658:("D_80867658","UNK_TYPE1","",0x1),
0x80867684:("D_80867684","UNK_TYPE1","",0x1),
0x80867688:("D_80867688","UNK_TYPE1","",0x1),
0x80867690:("D_80867690","UNK_TYPE1","",0x1),
0x80867698:("D_80867698","UNK_TYPE1","",0x1),
0x808676A0:("D_808676A0","UNK_TYPE1","",0x1),
0x808676B8:("D_808676B8","UNK_TYPE1","",0x1),
0x808676D0:("D_808676D0","UNK_TYPE1","",0x1),
0x808676D4:("D_808676D4","UNK_TYPE1","",0x1),
0x808676D8:("D_808676D8","UNK_TYPE1","",0x1),
0x808676E4:("D_808676E4","UNK_TYPE1","",0x1),
0x808676EC:("D_808676EC","UNK_TYPE1","",0x1),
0x808676F0:("D_808676F0","UNK_TYPE1","",0x1),
0x80867704:("D_80867704","UNK_TYPE1","",0x1),
0x80867708:("D_80867708","UNK_TYPE1","",0x1),
0x8086770C:("D_8086770C","UNK_TYPE1","",0x1),
0x808675D0:("sDoorSch_SwordsmansSchool","UNK_TYPE1","",0x1),
0x808675E4:("sDoorSch_PostOffice","UNK_TYPE1","",0x1),
0x80867634:("sDoorSch_LotteryShop","UNK_TYPE1","",0x1),
0x80867640:("sDoorSch_TradingPost","UNK_TYPE1","",0x1),
0x8086764C:("sDoorSch_CuriosityShop","UNK_TYPE1","",0x1),
0x80867658:("sDoorSch_LaundryPool","UNK_TYPE1","",0x1),
0x80867684:("sDoorSch_BombShop","UNK_TYPE1","",0x1),
0x80867688:("sDoorSch_TownShootingGallery","UNK_TYPE1","",0x1),
0x80867690:("sDoorSch_TreasureChestShop","UNK_TYPE1","",0x1),
0x80867698:("sDoorSch_HoneyDarlingShop","UNK_TYPE1","",0x1),
0x808676A0:("sDoorSch_MilkBar","UNK_TYPE1","",0x1),
0x808676B8:("sDoorSch_InnMainEntrance","UNK_TYPE1","",0x1),
0x808676D0:("sDoorSch_InnUpperEntrance","UNK_TYPE1","",0x1),
0x808676D4:("sDoorSch_InnGrannys","UNK_TYPE1","",0x1),
0x808676D8:("sDoorSch_InnStaffRoom","UNK_TYPE1","",0x1),
0x808676E4:("sDoorSch_InnKnifeChamber","UNK_TYPE1","",0x1),
0x808676EC:("sDoorSch_InnLargeSuite","UNK_TYPE1","",0x1),
0x808676F0:("sDoorSch_MayorsResidenceMainEntrance","UNK_TYPE1","",0x1),
0x80867704:("sDoorSch_MayorsResidenceMayorDotour","UNK_TYPE1","",0x1),
0x80867708:("sDoorSch_MayorsResidenceMadameAroma","UNK_TYPE1","",0x1),
0x8086770C:("sDoorSch_MayorsResidenceBedroom","UNK_TYPE1","",0x1),
0x80867710:("D_80867710","UNK_TYPE1","",0x1),
0x80867714:("D_80867714","UNK_TYPE1","",0x1),
0x8086771C:("D_8086771C","UNK_TYPE1","",0x1),
0x80867734:("D_80867734","UNK_TYPE1","",0x1),
0x8086773C:("D_8086773C","UNK_TYPE1","",0x1),
0x80867744:("D_80867744","UNK_TYPE1","",0x1),
0x8086775C:("D_8086775C","UNK_TYPE1","",0x1),
0x80867778:("D_80867778","UNK_TYPE1","",0x1),
0x8086777C:("D_8086777C","UNK_TYPE1","",0x1),
0x80867714:("sDoorSch_RomaniRanchMamasHouse","UNK_TYPE1","",0x1),
0x8086771C:("sDoorSch_RomaniRanchBarn","UNK_TYPE1","",0x1),
0x80867734:("sDoorSch_RomaniRanchCuccoShack","UNK_TYPE1","",0x1),
0x8086773C:("sDoorSch_RomaniRanchDoggyRacetrack","UNK_TYPE1","",0x1),
0x80867744:("sDoorSch_RomaniRanchBedroom","UNK_TYPE1","",0x1),
0x8086775C:("sDoorSch_IkanaCanyonMusicBoxHouse","UNK_TYPE1","",0x1),
0x80867778:("sDoorSch_DampesHouse","UNK_TYPE1","",0x1),
0x8086777C:("sDoorSch_MagicHagsPotionShop","UNK_TYPE1","",0x1),
0x80867780:("D_80867780","UNK_TYPE1","",0x1),
0x80867784:("D_80867784","UNK_TYPE1","",0x1),
0x8086778C:("D_8086778C","UNK_PTR","",0x4),
0x80867784:("sDoorSch_SwampShootingGallery","UNK_TYPE1","",0x1),
0x8086778C:("sDoorSchedules","UNK_PTR","",0x4),
0x8086780C:("En_Door_InitVars","UNK_TYPE1","",0x1),
0x8086782C:("sObjectInfo","UNK_TYPE2","",0x126),
0x80867954:("sInitChain","UNK_TYPE1","",0x1),
0x80867964:("sAnimations","AnimationHeader","[10]",0x28),
0x8086798C:("sAnimOpenFrames","u8","[10]",0x10),
0x80867998:("sAnimCloseFrames","u8","[10]",0x10),
0x808679A4:("D_808679A4","UNK_TYPE1","",0x1),
0x808679A4:("sDoorDLists","UNK_TYPE1","",0x1),
0x80867A20:("D_80867A20","f32","",0x4),
0x80867BC0:("D_80867BC0","UNK_TYPE1","",0x1),
0x80867BC0:("sDoorIsMilkBarMember","UNK_TYPE1","",0x1),
0x80869B30:("En_Box_InitVars","UNK_TYPE1","",0x1),
0x80869B50:("D_80869B50","UNK_TYPE1","",0x1),
0x80869B54:("D_80869B54","UNK_TYPE4","",0x4),

View File

@ -798,7 +798,8 @@ wordReplace = {
"func_8013E1C8": "SubS_ChangeAnimationBySpeedInfo",
"func_8013D9C8": "SubS_UpdateFidgetTables",
"SubS_FillLimbRotTables": "SubS_UpdateFidgetTables",
"func_8013A7C0": "SubS_FindDoor",
"func_8013A7C0": "SubS_FindScheduleDoor",
"SubS_FindDoor": "SubS_FindScheduleDoor",
"func_8013E640": "SubS_FindActorCustom",
"func_ActorCategoryIterateById": "SubS_FindActor",
"func_8013BB7C": "SubS_FindNearestActor",

View File

@ -2169,7 +2169,7 @@ asm/non_matchings/code/z_snap/func_8013A46C.s,func_8013A46C,0x8013A46C,0x16
asm/non_matchings/code/z_snap/func_8013A4C4.s,func_8013A4C4,0x8013A4C4,0x10
asm/non_matchings/code/z_snap/func_8013A504.s,func_8013A504,0x8013A504,0xB
asm/non_matchings/code/z_snap/func_8013A530.s,func_8013A530,0x8013A530,0xA4
asm/non_matchings/code/z_sub_s/SubS_FindDoor.s,SubS_FindDoor,0x8013A7C0,0x28
asm/non_matchings/code/z_sub_s/SubS_FindScheduleDoor.s,SubS_FindScheduleDoor,0x8013A7C0,0x28
asm/non_matchings/code/z_sub_s/SubS_DrawTransformFlexLimb.s,SubS_DrawTransformFlexLimb,0x8013A860,0xA8
asm/non_matchings/code/z_sub_s/SubS_DrawTransformFlex.s,SubS_DrawTransformFlex,0x8013AB00,0x9B
asm/non_matchings/code/z_sub_s/SubS_InCsMode.s,SubS_InCsMode,0x8013AD6C,0xC

1 asm/non_matchings/code/z_en_a_keep/EnAObj_Init.s EnAObj_Init 0x800A5AC0 0x2B
2169 asm/non_matchings/code/z_snap/func_8013A4C4.s func_8013A4C4 0x8013A4C4 0x10
2170 asm/non_matchings/code/z_snap/func_8013A504.s func_8013A504 0x8013A504 0xB
2171 asm/non_matchings/code/z_snap/func_8013A530.s func_8013A530 0x8013A530 0xA4
2172 asm/non_matchings/code/z_sub_s/SubS_FindDoor.s asm/non_matchings/code/z_sub_s/SubS_FindScheduleDoor.s SubS_FindDoor SubS_FindScheduleDoor 0x8013A7C0 0x28
2173 asm/non_matchings/code/z_sub_s/SubS_DrawTransformFlexLimb.s SubS_DrawTransformFlexLimb 0x8013A860 0xA8
2174 asm/non_matchings/code/z_sub_s/SubS_DrawTransformFlex.s SubS_DrawTransformFlex 0x8013AB00 0x9B
2175 asm/non_matchings/code/z_sub_s/SubS_InCsMode.s SubS_InCsMode 0x8013AD6C 0xC