diff --git a/config/SOUE01/rels/d_a_obj_doorNP/symbols.txt b/config/SOUE01/rels/d_a_obj_doorNP/symbols.txt index f00a5c190..0388c66e9 100644 --- a/config/SOUE01/rels/d_a_obj_doorNP/symbols.txt +++ b/config/SOUE01/rels/d_a_obj_doorNP/symbols.txt @@ -2,98 +2,94 @@ _prolog = .text:0x00000000; // type:function size:0x2C scope:global _epilog = .text:0x00000030; // type:function size:0x2C scope:global _unresolved = .text:0x00000060; // type:function size:0x4 scope:global dAcOdoor_c_classInit__Fv = .text:0x00000070; // type:function size:0x110 -fn_572_180 = .text:0x00000180; // type:function size:0x68 -fn_572_1F0 = .text:0x000001F0; // type:function size:0x4C -fn_572_240 = .text:0x00000240; // type:function size:0x4C -fn_572_290 = .text:0x00000290; // type:function size:0x58 -fn_572_2F0 = .text:0x000002F0; // type:function size:0x4C -getDoorTalk = .text:0x00000340; // type:function size:0xC -fn_572_350 = .text:0x00000350; // type:function size:0x7C -fn_572_3D0 = .text:0x000003D0; // type:function size:0x40 -fn_572_410 = .text:0x00000410; // type:function size:0x7C -fn_572_490 = .text:0x00000490; // type:function size:0x68 -fn_572_500 = .text:0x00000500; // type:function size:0x1EC -AcODoor__init = .text:0x000006F0; // type:function size:0x34C -AcODoor__init2 = .text:0x00000A40; // type:function size:0x7D4 -fn_572_1220 = .text:0x00001220; // type:function size:0x24 -fn_572_1250 = .text:0x00001250; // type:function size:0x16C4 -fn_572_2920 = .text:0x00002920; // type:function size:0x1C -AcODoor__update = .text:0x00002940; // type:function size:0x808 -fn_572_3150 = .text:0x00003150; // type:function size:0x98 +getDoorMapping__26@unnamed@d_a_obj_door_cpp@FUlRPCQ226@unnamed@d_a_obj_door_cpp@15DoorFileMapping = .text:0x00000180; // type:function size:0x68 +getDoorResName__26@unnamed@d_a_obj_door_cpp@FUlRPCc = .text:0x000001F0; // type:function size:0x4C +getDoorMdlName__26@unnamed@d_a_obj_door_cpp@FUlRPCc = .text:0x00000240; // type:function size:0x4C +getDoorCallbackTypeMapped__26@unnamed@d_a_obj_door_cpp@FUcRUc = .text:0x00000290; // type:function size:0x58 +isDoubleDoorType__26@unnamed@d_a_obj_door_cpp@Fl = .text:0x000002F0; // type:function size:0x4C +getDoorInteractionName__26@unnamed@d_a_obj_door_cpp@Fv = .text:0x00000340; // type:function size:0xC +isInSandshipBoss__26@unnamed@d_a_obj_door_cpp@Fv = .text:0x00000350; // type:function size:0x7C +isInEvent__26@unnamed@d_a_obj_door_cpp@FPCc = .text:0x000003D0; // type:function size:0x40 +isInTimeDoorEvent__26@unnamed@d_a_obj_door_cpp@Fv = .text:0x00000410; // type:function size:0x7C +checkRoom__26@unnamed@d_a_obj_door_cpp@FScRb = .text:0x00000490; // type:function size:0x68 +createHeap__10dAcOdoor_cFv = .text:0x00000500; // type:function size:0x1EC +actorCreate__10dAcOdoor_cFv = .text:0x000006F0; // type:function size:0x34C +actorPostCreate__10dAcOdoor_cFv = .text:0x00000A40; // type:function size:0x7D4 +doDelete__10dAcOdoor_cFv = .text:0x00001220; // type:function size:0x24 +actorExecuteInEvent__10dAcOdoor_cFv = .text:0x00001250; // type:function size:0x16C4 +calcTimer__4sLibFPUc_Uc = .text:0x00002920; // type:function size:0x1C +actorExecute__10dAcOdoor_cFv = .text:0x00002940; // type:function size:0x808 +draw__10dAcOdoor_cFv = .text:0x00003150; // type:function size:0x98 isLocked__10dAcOdoor_cFv = .text:0x000031F0; // type:function size:0x158 -fn_572_3350 = .text:0x00003350; // type:function size:0x84 -fn_572_33E0 = .text:0x000033E0; // type:function size:0xC -fn_572_33F0 = .text:0x000033F0; // type:function size:0x78 -fn_572_3470 = .text:0x00003470; // type:function size:0x7C -fn_572_34F0 = .text:0x000034F0; // type:function size:0x78 -fn_572_3570 = .text:0x00003570; // type:function size:0x7C -AcODoor__handleDoorPullEvent = .text:0x000035F0; // type:function size:0x20 -fn_572_3610 = .text:0x00003610; // type:function size:0x4 -AcODoor__handlePushEvent = .text:0x00003620; // type:function size:0x20 -fn_572_3640 = .text:0x00003640; // type:function size:0x4 -AcODoor__handleNormalEvent = .text:0x00003650; // type:function size:0xB0 -fn_572_3700 = .text:0x00003700; // type:function size:0x4 -fn_572_3710 = .text:0x00003710; // type:function size:0x4 -AcODoor__handleLockedPullEvent = .text:0x00003720; // type:function size:0x70 -AcODoor__handleLockedPushEvent = .text:0x00003790; // type:function size:0x70 -AcODoor__handleLockedEvent = .text:0x00003800; // type:function size:0x5C -AcODoor__pullLockedCallback = .text:0x00003860; // type:function size:0x68 -AcODoor__lockedPushCallback = .text:0x000038D0; // type:function size:0x68 -AcODoor__handleShutterUnlockEvent = .text:0x00003940; // type:function size:0x6C -fn_572_39B0 = .text:0x000039B0; // type:function size:0x1EC -fn_572_3BA0 = .text:0x00003BA0; // type:function size:0x148 -fn_572_3CF0 = .text:0x00003CF0; // type:function size:0x3C -fn_572_3D30 = .text:0x00003D30; // type:function size:0x4 -AcODoor__performInteraction = .text:0x00003D40; // type:function size:0x1EC -AcODoor__isKeyLocked = .text:0x00003F30; // type:function size:0xC -AcODoor__getSubtype2 = .text:0x00003F40; // type:function size:0xC -AcODoor__getParamSceneflag = .text:0x00003F50; // type:function size:0xC -fn_572_3F60 = .text:0x00003F60; // type:function size:0xC -fn_572_3F70 = .text:0x00003F70; // type:function size:0xC -fn_572_3F80 = .text:0x00003F80; // type:function size:0xC -fn_572_3F90 = .text:0x00003F90; // type:function size:0x24 -fn_572_3FC0 = .text:0x00003FC0; // type:function size:0xC -fn_572_3FD0 = .text:0x00003FD0; // type:function size:0xC -fn_572_3FE0 = .text:0x00003FE0; // type:function size:0xC -fn_572_3FF0 = .text:0x00003FF0; // type:function size:0xC -fn_572_4000 = .text:0x00004000; // type:function size:0xC -fn_572_4010 = .text:0x00004010; // type:function size:0xC -fn_572_4020 = .text:0x00004020; // type:function size:0xC -fn_572_4030 = .text:0x00004030; // type:function size:0xC -AcODoor__setRoomId = .text:0x00004040; // type:function size:0x8 -fn_572_4050 = .text:0x00004050; // type:function size:0x8 -fn_572_4060 = .text:0x00004060; // type:function size:0x8 -fn_572_4070 = .text:0x00004070; // type:function size:0x8 -fn_572_4080 = .text:0x00004080; // type:function size:0x8 -fn_572_4090 = .text:0x00004090; // type:function size:0xC -fn_572_40A0 = .text:0x000040A0; // type:function size:0xC -fn_572_40B0 = .text:0x000040B0; // type:function size:0xC -fn_572_40C0 = .text:0x000040C0; // type:function size:0xC -fn_572_40D0 = .text:0x000040D0; // type:function size:0xC -fn_572_40E0 = .text:0x000040E0; // type:function size:0xC -fn_572_40F0 = .text:0x000040F0; // type:function size:0xC -fn_572_4100 = .text:0x00004100; // type:function size:0xC -fn_572_4110 = .text:0x00004110; // type:function size:0xC -fn_572_4120 = .text:0x00004120; // type:function size:0xC -fn_572_4130 = .text:0x00004130; // type:function size:0xC -fn_572_4140 = .text:0x00004140; // type:function size:0xC -fn_572_4150 = .text:0x00004150; // type:function size:0x90 -AcODoor__triggerExit = .text:0x000041E0; // type:function size:0x7C -AcODoor__isThisTheDoorFromSealedTempleToSpiralAfterSkykeep = .text:0x00004260; // type:function size:0xAC -fn_572_4310 = .text:0x00004310; // type:function size:0x28 -fn_572_4338 = .text:0x00004338; // type:function size:0x4 -fn_572_4340 = .text:0x00004340; // type:function size:0x28 -fn_572_4368 = .text:0x00004368; // type:function size:0x4 -fn_572_4370 = .text:0x00004370; // type:function size:0x84 -AcODoor__getOpenedDoorSide = .text:0x00004400; // type:function size:0x10 -AcODoor__hasFlowEntrypoint = .text:0x00004410; // type:function size:0x18 -fn_572_4430 = .text:0x00004430; // type:function size:0xC -fn_572_4440 = .text:0x00004440; // type:function size:0xE4 -AcODoor__playerInInteractRange = .text:0x00004530; // type:function size:0xD0 -fn_572_4600 = .text:0x00004600; // type:function size:0xE4 -AcODoor__triggerDoorTalk = .text:0x000046F0; // type:function size:0x68 +canOpen__10dAcOdoor_cFv = .text:0x00003350; // type:function size:0x84 +fn_572_33E0__10dAcOdoor_cFv = .text:0x000033E0; // type:function size:0xC +startPullEventWithoutCallback__10dAcOdoor_cFPv = .text:0x000033F0; // type:function size:0x78 +startPullEventWithCallback__10dAcOdoor_cFPv = .text:0x00003470; // type:function size:0x7C +startPushEventWithoutCallback__10dAcOdoor_cFPv = .text:0x000034F0; // type:function size:0x78 +startPushEventWithCallback__10dAcOdoor_cFPv = .text:0x00003570; // type:function size:0x7C +startPullEvent__10dAcOdoor_cFPv = .text:0x000035F0; // type:function size:0x24 +startPushEvent__10dAcOdoor_cFPv = .text:0x00003620; // type:function size:0x24 +startOpenEvent__10dAcOdoor_cFPv = .text:0x00003650; // type:function size:0xB0 +doorPullEventCallback__10dAcOdoor_cFPv = .text:0x00003700; // type:function size:0x4 +doorPushEventCallback__10dAcOdoor_cFPv = .text:0x00003710; // type:function size:0x4 +startDoorPullLockedEvent__10dAcOdoor_cFPv = .text:0x00003720; // type:function size:0x70 +startDoorPushLockedEvent__10dAcOdoor_cFPv = .text:0x00003790; // type:function size:0x70 +startLockedEvent__10dAcOdoor_cFPv = .text:0x00003800; // type:function size:0x5C +pullLockedEventCallback__10dAcOdoor_cFPv = .text:0x00003860; // type:function size:0x68 +pushLockedEventCallback__10dAcOdoor_cFPv = .text:0x000038D0; // type:function size:0x68 +startUnlockEvent__10dAcOdoor_cFv = .text:0x00003940; // type:function size:0x6C +unlockEventCallback__10dAcOdoor_cFPv = .text:0x000039B0; // type:function size:0x1EC +openCallbackCommon__10dAcOdoor_cFPv = .text:0x00003BA0; // type:function size:0x148 +registerInEvent__10dAcOdoor_cFv = .text:0x00003CF0; // type:function size:0x3C +unkVirtFunc_0x6C__10dAcOdoor_cFv = .text:0x00003D30; // type:function size:0x4 +doInteraction__10dAcOdoor_cFl = .text:0x00003D40; // type:function size:0x1EC +getLockParameter__10dAcOdoor_cFv = .text:0x00003F30; // type:function size:0xC +getLockBehavior__10dAcOdoor_cFv = .text:0x00003F40; // type:function size:0xC +getSceneflag__10dAcOdoor_cFv = .text:0x00003F50; // type:function size:0xC +getDoorCallbackType__10dAcOdoor_cFv = .text:0x00003F60; // type:function size:0xC +getFrontRoomParam__10dAcOdoor_cFv = .text:0x00003F70; // type:function size:0xC +getBackRoomParam__10dAcOdoor_cFv = .text:0x00003F80; // type:function size:0xC +getFailedToOpenFlag__10dAcOdoor_cFv = .text:0x00003F90; // type:function size:0x24 +getInteractionMinX__10dAcOdoor_cFv = .text:0x00003FC0; // type:function size:0xC +getInteractionMaxX__10dAcOdoor_cFv = .text:0x00003FD0; // type:function size:0xC +getInteractionMinZ__10dAcOdoor_cFv = .text:0x00003FE0; // type:function size:0xC +getInteractionMaxZ__10dAcOdoor_cFv = .text:0x00003FF0; // type:function size:0xC +getInteractionLockMinX__10dAcOdoor_cFv = .text:0x00004000; // type:function size:0xC +getInteractionLockMaxX__10dAcOdoor_cFv = .text:0x00004010; // type:function size:0xC +getInteractionLockMinZ__10dAcOdoor_cFv = .text:0x00004020; // type:function size:0xC +getInteractionLockMaxZ__10dAcOdoor_cFv = .text:0x00004030; // type:function size:0xC +setRoomId__10dAcOdoor_cFSc = .text:0x00004040; // type:function size:0x8 +setFlag__10dAcOdoor_cFUl = .text:0x00004050; // type:function size:0x8 +setEventCallbackType__10dAcOdoor_cFUc = .text:0x00004060; // type:function size:0x8 +setFrontRoom__10dAcOdoor_cFSc = .text:0x00004070; // type:function size:0x8 +setBackRoom__10dAcOdoor_cFSc = .text:0x00004080; // type:function size:0x8 +setDoubleDoor__10dAcOdoor_cFv = .text:0x00004090; // type:function size:0xC +setNotDoubleDoor__10dAcOdoor_cFv = .text:0x000040A0; // type:function size:0xC +setSingleDoor__10dAcOdoor_cFv = .text:0x000040B0; // type:function size:0xC +setNotSingleDoor__10dAcOdoor_cFv = .text:0x000040C0; // type:function size:0xC +setInSandshipBoss__10dAcOdoor_cFv = .text:0x000040D0; // type:function size:0xC +isTimeDoorEventActive__10dAcOdoor_cCFv = .text:0x000040E0; // type:function size:0xC +setTimeDoorEventActive__10dAcOdoor_cFv = .text:0x000040F0; // type:function size:0xC +setTimeDoorEventInactive__10dAcOdoor_cFv = .text:0x00004100; // type:function size:0xC +setTimeEffected__10dAcOdoor_cFv = .text:0x00004110; // type:function size:0xC +setTimeStatic__10dAcOdoor_cFv = .text:0x00004120; // type:function size:0xC +checkFrontRoom__10dAcOdoor_cCFRb = .text:0x00004130; // type:function size:0xC +checkBackRoom__10dAcOdoor_cCFRb = .text:0x00004140; // type:function size:0xC +checkRooms__10dAcOdoor_cCFRb = .text:0x00004150; // type:function size:0x90 +triggerExit__10dAcOdoor_cFv = .text:0x000041E0; // type:function size:0x7C +isLeavingSealedTempleSideDoorPostSkyKeep__10dAcOdoor_cCFv = .text:0x00004260; // type:function size:0xAC +transitionPushRoomFlags__10dAcOdoor_cCFv = .text:0x00004310; // type:function size:0x2C +transitionPullRoomFlags__10dAcOdoor_cCFv = .text:0x00004340; // type:function size:0x2C +isPositionInFrontOfDoor__10dAcOdoor_cCFRC7mVec3_c = .text:0x00004370; // type:function size:0x84 +checkPullDoor__10dAcOdoor_cCFv = .text:0x00004400; // type:function size:0x10 +hasFlowEntryPoint__10dAcOdoor_cFv = .text:0x00004410; // type:function size:0x18 +isTimeEffected__10dAcOdoor_cCFv = .text:0x00004430; // type:function size:0xC +setDoorKnobPosition__10dAcOdoor_cFv = .text:0x00004440; // type:function size:0xE4 +isPlayerInteractable__10dAcOdoor_cCFv = .text:0x00004530; // type:function size:0xD0 +isPlayerInteractableLocked__10dAcOdoor_cCFv = .text:0x00004600; // type:function size:0xE4 +playInteractionLocked__10dAcOdoor_cFv = .text:0x000046F0; // type:function size:0x68 __dt__10dAcOdoor_cFv = .text:0x00004760; // type:function size:0xE8 -fn_572_4850 = .text:0x00004850; // type:function size:0x144 +__sinit_\d_a_obj_door_cpp = .text:0x00004850; // type:function size:0x144 scope:local _ctors = .ctors:0x00000000; // type:label scope:global _dtors = .dtors:0x00000000; // type:label scope:global lbl_572_rodata_0 = .rodata:0x00000000; // type:object size:0x20 data:float diff --git a/config/SOUE01/rels/d_a_obj_fenceNP/symbols.txt b/config/SOUE01/rels/d_a_obj_fenceNP/symbols.txt index b5ed5c3e0..658ac9b01 100644 --- a/config/SOUE01/rels/d_a_obj_fenceNP/symbols.txt +++ b/config/SOUE01/rels/d_a_obj_fenceNP/symbols.txt @@ -21,11 +21,11 @@ getStateID__80sStateMgr_c<11dAcOFence_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13 fn_550_D30 = .text:0x00000D30; // type:function size:0x304 fn_550_1040 = .text:0x00001040; // type:function size:0x13C fn_550_1180 = .text:0x00001180; // type:function size:0x28 -fn_550_11B0 = .text:0x000011B0; // type:function size:0xA0 -fn_550_1250 = .text:0x00001250; // type:function size:0x50 +fn_550_11B0__11dAcOFence_cCFv = .text:0x000011B0; // type:function size:0xA0 +fn_550_1250__11dAcOFence_cFv = .text:0x00001250; // type:function size:0x50 changeState__80sStateMgr_c<11dAcOFence_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>FRC12sStateIDIf_c = .text:0x000012A0; // type:function size:0x10 -fn_550_12B0 = .text:0x000012B0; // type:function size:0x10 -fn_550_12C0 = .text:0x000012C0; // type:function size:0x10 +fn_550_12B0__11dAcOFence_cFv = .text:0x000012B0; // type:function size:0x10 +fn_550_12C0__11dAcOFence_cFv = .text:0x000012C0; // type:function size:0x10 initializeState_WaitOpen__11dAcOFence_cFv = .text:0x000012D0; // type:function size:0x94 executeState_WaitOpen__11dAcOFence_cFv = .text:0x00001370; // type:function size:0x168 finalizeState_WaitOpen__11dAcOFence_cFv = .text:0x000014E0; // type:function size:0x4 @@ -142,4 +142,4 @@ lbl_550_bss_118 = .bss:0x00000118; // type:object size:0x40 data:4byte lbl_550_bss_158 = .bss:0x00000158; // type:object size:0x40 data:4byte lbl_550_bss_198 = .bss:0x00000198; // type:object size:0x40 data:4byte lbl_550_bss_1D8 = .bss:0x000001D8; // type:object size:0x40 data:4byte -lbl_550_bss_218 = .bss:0x00000218; // type:object size:0x30 +StateID_RequestConfineEvent__11dAcOFence_c = .bss:0x00000218; // type:object size:0x30 diff --git a/config/SOUE01/rels/d_a_obj_windmillNP/symbols.txt b/config/SOUE01/rels/d_a_obj_windmillNP/symbols.txt index 42e9ce53f..9a7ae51a6 100644 --- a/config/SOUE01/rels/d_a_obj_windmillNP/symbols.txt +++ b/config/SOUE01/rels/d_a_obj_windmillNP/symbols.txt @@ -80,7 +80,7 @@ lbl_374_data_190 = .data:0x00000190; // type:object size:0x198 scope:local __vt__29sFStateID_c<14dAcOwindmill_c> = .data:0x00000328; // type:object size:0x34 __global_destructor_chain = .bss:0x00000000; // type:object size:0x4 scope:global lbl_374_bss_8 = .bss:0x00000008; // type:object size:0x10 scope:local data:4byte -AcOwindmill__STATE_WAIT = .bss:0x00000018; // type:object size:0x40 data:4byte +StateID_Wait__14dAcOwindmill_c = .bss:0x00000018; // type:object size:0x40 data:4byte AcOwindmill__STATE_CAMERA_MOVE = .bss:0x00000058; // type:object size:0x40 data:4byte AcOwindmill__STATE_MOVE = .bss:0x00000098; // type:object size:0x80 data:4byte AcOwindmill__STATE_COLLECT_STICK = .bss:0x00000118; // type:object size:0x30 data:4byte diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 587eb1c62..e056ee9cb 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -1138,7 +1138,7 @@ fn_8002ECD0 = .text:0x8002ECD0; // type:function size:0x50 fn_8002ED20 = .text:0x8002ED20; // type:function size:0x88 fn_8002edb0__12dAcObjBase_cFRQ23m3d15mShadowCircle_cRQ23m3d6smdl_cPC7mQuat_cllf = .text:0x8002EDB0; // type:function size:0x8C drawShadow__12dAcObjBase_cFRQ23m3d15mShadowCircle_cPvRC6mMtx_cPC7mQuat_clllllf = .text:0x8002EE40; // type:function size:0xFC -actorSpawnAtActor2 = .text:0x8002EF40; // type:function size:0x24 +create__12dAcObjBase_cFP12dAcObjBase_cQ28fProfile14PROFILE_NAME_eUlPC7mVec3_cPC7mAng3_cPC7mVec3_cUlUl = .text:0x8002EF40; // type:function size:0x24 fn_8002EF70 = .text:0x8002EF70; // type:function size:0x28 fn_8002EFA0 = .text:0x8002EFA0; // type:function size:0x50 fn_8002eff0__12dAcObjBase_cFRCfRCsP8cCcD_ObjRCfRCf = .text:0x8002EFF0; // type:function size:0x194 @@ -3525,7 +3525,7 @@ getCurrentEventCommand__17ActorEventRelatedCFv = .text:0x8009CF10; // type:funct ActorEventRelated__getSomeEventRelatedNumber = .text:0x8009CFA0; // type:function size:0x80 isAdvance__17ActorEventRelatedFv = .text:0x8009D020; // type:function size:0x34 advanceNext__17ActorEventRelatedFv = .text:0x8009D060; // type:function size:0x50 -ActorEventRelated__getSingleIntData2 = .text:0x8009D0B0; // type:function size:0x8C +getSingleShortData__17ActorEventRelatedFPiUlUl = .text:0x8009D0B0; // type:function size:0x8C getSingleIntData__17ActorEventRelatedFPiUlUl = .text:0x8009D140; // type:function size:0x8C getSingleFloatData__17ActorEventRelatedFPfUlUl = .text:0x8009D1D0; // type:function size:0x8C getSingleVecData__17ActorEventRelatedFP7mVec3_cUlUl = .text:0x8009D260; // type:function size:0x9C @@ -3568,7 +3568,7 @@ fn_8009F850 = .text:0x8009F850; // type:function size:0x134 fn_8009F990__12EventManagerFv = .text:0x8009F990; // type:function size:0x80 fn_8009FA10 = .text:0x8009FA10; // type:function size:0x8 attachSkipEvent = .text:0x8009FA20; // type:function size:0x1A0 -setAsEvent = .text:0x8009FBC0; // type:function size:0x120 +setEvent__12EventManagerFP9dAcBase_cP5EventP9dAcBase_c = .text:0x8009FBC0; // type:function size:0x120 changeOwnEvent__12EventManagerFP9dAcBase_cP9dAcBase_cP5Eventi = .text:0x8009FCE0; // type:function size:0x11C fn_8009FE00 = .text:0x8009FE00; // type:function size:0x124 isInEvent__12EventManagerFP9dAcBase_cPCc = .text:0x8009FF30; // type:function size:0x10C @@ -9879,8 +9879,8 @@ fn_80178E90 = .text:0x80178E90; // type:function size:0x40 fn_80178ED0 = .text:0x80178ED0; // type:function size:0x114 __dt__13dAcBirdBase_cFv = .text:0x80178FF0; // type:function size:0xDC __dt__Q213dAcBirdBase_c10callback_cFv = .text:0x801790D0; // type:function size:0x58 -__ct__16dAcObjDoor_cFv = .text:0x80179130; // type:function size:0x58 -fn_80179190 = .text:0x80179190; // type:function size:0x74 +__ct__12dAcObjDoor_cFv = .text:0x80179130; // type:function size:0x58 +__dt__12dAcObjDoor_cFv = .text:0x80179190; // type:function size:0x74 ActorDoorBase__hasVisitedRoomIdMaybe = .text:0x80179210; // type:function size:0x14 fn_80179230 = .text:0x80179230; // type:function size:0x4 fn_80179240 = .text:0x80179240; // type:function size:0x4 @@ -10420,13 +10420,13 @@ fn_80194A90 = .text:0x80194A90; // type:function size:0x58 checkStatueFlag__10dAcOSave_cCFv = .text:0x80194AF0; // type:function size:0x28 fn_80194B20 = .text:0x80194B20; // type:function size:0x8 fn_80194B30 = .text:0x80194B30; // type:function size:0x44 -fn_80194B80 = .text:0x80194B80; // type:function size:0x8 +getConnectedDoorRef__10dAcOdoor_cFv = .text:0x80194B80; // type:function size:0x8 fn_80194B90 = .text:0x80194B90; // type:function size:0x8 -fn_80194BA0 = .text:0x80194BA0; // type:function size:0x30 +isConnectedToOtherDoor__10dAcOdoor_cCFv = .text:0x80194BA0; // type:function size:0x30 fn_80194BD0 = .text:0x80194BD0; // type:function size:0x18 fn_80194BF0 = .text:0x80194BF0; // type:function size:0x24 fn_80194C20 = .text:0x80194C20; // type:function size:0x48 -fn_80194C70 = .text:0x80194C70; // type:function size:0x70 +stepTowards__10dAcOdoor_cCFR7mVec3_c = .text:0x80194C70; // type:function size:0x70 getImprisonedPtr = .text:0x80194CE0; // type:function size:0x8 fn_80194CF0 = .text:0x80194CF0; // type:function size:0x128 dAcOClef__getTadtoneGroupIndex = .text:0x80194E20; // type:function size:0x38 @@ -10960,9 +10960,9 @@ waitForRooms__8dStage_cFv = .text:0x801B3930; // type:function size:0x30 setRoom__8dStage_cFiP7dRoom_c = .text:0x801B3960; // type:function size:0x10 getRoom__8dStage_cFl = .text:0x801B3970; // type:function size:0x10 handleRoomChange__8dStage_cFi = .text:0x801B3980; // type:function size:0x114 -RoomManager__updateRoomFlags = .text:0x801B3AA0; // type:function size:0x134 +updateRoomFlags__8dStage_cFii = .text:0x801B3AA0; // type:function size:0x134 RoomManager__checkOtherRoomLoaded = .text:0x801B3BE0; // type:function size:0x78 -fn_801B3C60 = .text:0x801B3C60; // type:function size:0x9C +fn_801B3C60__8dStage_cFi = .text:0x801B3C60; // type:function size:0x9C fadeIn__8dStage_cFlUs = .text:0x801B3D00; // type:function size:0xA8 fadeOut__8dStage_cFlUs = .text:0x801B3DB0; // type:function size:0xA8 forceFadeOut__8dStage_cFv = .text:0x801B3E60; // type:function size:0x40 diff --git a/include/d/a/d_a_base.h b/include/d/a/d_a_base.h index 97e33e471..45b2336f7 100644 --- a/include/d/a/d_a_base.h +++ b/include/d/a/d_a_base.h @@ -125,6 +125,9 @@ class dAcBase_c : public dBase_c { public: dAcBase_c(); + void setSubtype(u8 sub) { + mSubtype = sub; + } void setPosition(const mVec3_c &r) { mPosition = r; } diff --git a/include/d/a/obj/d_a_obj_base.h b/include/d/a/obj/d_a_obj_base.h index 3deba1ae1..039def404 100644 --- a/include/d/a/obj/d_a_obj_base.h +++ b/include/d/a/obj/d_a_obj_base.h @@ -181,6 +181,11 @@ class dAcObjBase_c : public dAcBase_c { const char *name, u32 roomId, u32 params1, const mVec3_c *pos, const mAng3_c *rot, const mVec3_c *scale, u32 params2, u16 id, s8 viewclipId ); + static dAcObjBase_c *create( + dAcObjBase_c *, fProfile::PROFILE_NAME_e actorId, u32 params1, const mVec3_c *pos, const mAng3_c *rot, + const mVec3_c *scale, u32 params2, u32 roomId + ); + static dAcObjBase_c *findObject(fProfile::PROFILE_NAME_e actorId, fLiNdBa_c *refList, dAcObjBase_c *parent); static dAcObjBase_c *getNextObject(fLiMgBa_c *ref, dAcObjBase_c *parent); bool isPlayer(); diff --git a/include/d/a/obj/d_a_obj_door.h b/include/d/a/obj/d_a_obj_door.h index 6681801eb..4992c9544 100644 --- a/include/d/a/obj/d_a_obj_door.h +++ b/include/d/a/obj/d_a_obj_door.h @@ -1,16 +1,319 @@ #ifndef D_A_OBJ_DOOR_H #define D_A_OBJ_DOOR_H +#include "common.h" +#include "d/a/d_a_base.h" +#include "d/a/obj/d_a_obj_base.h" #include "d/a/obj/d_a_obj_door_base.h" +#include "m/m3d/m_anmmdl.h" +#include "m/m3d/m_smdl.h" +#include "m/m_mtx.h" +#include "m/m_vec.h" +#include "toBeSorted/actor_event.h" +#include "toBeSorted/d_emitter.h" +#include "toBeSorted/d_flow_mgr.h" + +struct dTimeBits { + dTimeBits() : field_0x00(false), field_0x01(false) {} + bool field_0x00; + bool field_0x01; +}; + +class dAcOLock_c; class dAcOdoor_c : public dAcObjDoor_c { public: - dAcOdoor_c() {} + enum Subtype_e { + DOOR_NORMAL, ///< DoorA00 - Normal Wooden Door + DOOR_METAL, ///< DoorA01 - Metal Door - Academy(bathrooms) + DOOR_DOUBLE, ///< DoorC00 - Normal Double Doors + DOOR_DOUBLE_OUTSIDE, ///< DoorC01 - Outdoor Double Doors - Academy(to outside) + DOOR_TEMPLE_SIDE, ///< DoorB00 - Sealed Temple Side Doors + DOOR_SANDSEA_TIMESHIFT, ///< DoorE - Sandsea Timeshift Door + DOOR_BATREAUX, ///< DoorA02 - Batreaux's Door + DOOR_TEMPLE_MAIN, ///< DoorF - Sealed Temple Main Door + DOOR_SPARRING_HALL, ///< DoorH - Sparring Hall Outer Doors + }; + + enum LockType_e { + LOCK_NONE = 0, ///< Door does not have a lock + LOCK_KEY = 1, ///< Door usually is locked + }; + + enum LockBehavior_e { + LOCK_NEVER = 0, ///< Door is always unlocked + LOCK_NOT_SET = 1, ///< Door is locked when mSceneflag is unset + LOCK_NEVER1 = 2, ///< Door is always unlocked (Kukiel's House) + LOCK_TIMESHIFT = 3, ///< Door is locked when mSceneflag is unset (Timeshift) + LOCK_SET = 4, ///< Door is locked when mSceneflag is set + LOCK_DAY = 5, ///< Door is locked during the day + LOCK_NIGHT = 6, ///< Door is locked during the night + LOCK_MAX, + }; + +public: + dAcOdoor_c() + : mEventRelated(*this, nullptr), + mEmmiterL(this), + mEmmiterR(this), + mFlags(0), + mExitTimer(0), + mbInSandshipBoss(false), + field_0x5BA(false) {} virtual ~dAcOdoor_c() {} + virtual int doDelete() override; + virtual int draw() override; + virtual bool createHeap() override; + virtual int actorCreate() override; + virtual int actorPostCreate() override; + virtual int actorExecute() override; + virtual int actorExecuteInEvent() override; + virtual void registerInEvent() override; + virtual void unkVirtFunc_0x6C() override; + virtual void doInteraction(s32 /* InteractionType */) override; + virtual bool canOpen() override; + + /** Gets whether the player can open the door */ bool isLocked(); + /** fn_572_33E0 - I Think this gets the Door open range*/ + static f32 fn_572_33E0(); + + /** Self Explanatory */ + void startPullEventWithoutCallback(void *zevData); + + /** Self Explanatory */ + void startPullEventWithCallback(void *zevData); + + /** Self Explanatory */ + void startPushEventWithoutCallback(void *zevData); + + /** Self Explanatory */ + void startPushEventWithCallback(void *zevData); + + /** Self Explanatory */ + void startPullEvent(void *zevData); + + /** Self Explanatory */ + void startPushEvent(void *zevData); + + /** Self Explanatory */ + void startOpenEvent(void *zevData); + + /** Self Explanatory */ + static void doorPullEventCallback(void *); + + /** Self Explanatory */ + static void doorPushEventCallback(void *); + + /** Self Explanatory */ + void startDoorPullLockedEvent(void *zevData); + + /** Self Explanatory */ + void startDoorPushLockedEvent(void *zevData); + + /** Self Explanatory */ + void startLockedEvent(void *zevData); + + /** Self Explanatory */ + static void pullLockedEventCallback(void *); + + /** Self Explanatory */ + static void pushLockedEventCallback(void *); + + /** Self Explanatory */ + void startUnlockEvent(); + + /** Self Explanatory */ + static void unlockEventCallback(void *); + + /** Self Explanatory */ + static void openCallbackCommon(void *); + + /** Returns if the door is physically locked with the dAcOLock_c Actor */ + s32 getLockParameter(); + + /** Gets the behavior of being locked when not locked with the dAcOLock_c Actor */ + s32 getLockBehavior(); + + /** Get Scenflag used for locking status */ + u8 getSceneflag(); + + /** Gets whether the door has callbacks enabled */ + u8 getDoorCallbackType(); + + /** getFrontRoomParam */ + u8 getFrontRoomParam(); // (mRotation.z >> 4) & 0x3F + + /** getBackRoomParam */ + u8 getBackRoomParam(); // (mRotation.z >> 10) & 0x3F + + /** Gets the Flag set when failed to open - Called from Try Locked Callback */ + u16 getFailedToOpenFlag(); + + /** Interaction Radius -X */ + static f32 getInteractionMinX(); + + /** Interaction Radius +X */ + static f32 getInteractionMaxX(); + + /** Interaction Radius -Z */ + static f32 getInteractionMinZ(); + + /** Interaction Radius +Z */ + static f32 getInteractionMaxZ(); + + /** Interaction Radius -X - Door has Lock */ + static f32 getInteractionLockMinX(); + + /** Interaction Radius +X - Door has Lock */ + static f32 getInteractionLockMaxX(); + + /** Interaction Radius -Z - Door has Lock */ + static f32 getInteractionLockMinZ(); + + /** Interaction Radius +Z - Door has Lock */ + static f32 getInteractionLockMaxZ(); + + /** Sets the RoomID */ + void setRoomId(s8 roomId); + + /** Set Flag - Usually Time Door related */ + void setFlag(u32 flags); + + /** Sets the behavior on Event creation */ + void setEventCallbackType(u8); + + /** setFrontRoom */ + void setFrontRoom(s8); // mFrontRoomId = in + + /** setBackRoom */ + void setBackRoom(s8); // mBackRoomId = in + + /** Sets status indicating it can be a double door */ + void setDoubleDoor(); + + /** Sets status indicating it cant be a double door */ + void setNotDoubleDoor(); + + /** Sets status indicating its a single door / Main door */ + void setSingleDoor(); + + /** Sets status indicating its not a single door / not Main door */ + void setNotSingleDoor(); + + /** setInSandshipBoss */ + void setInSandshipBoss(); // mbInSandshipBoss = true + + /** isTimeDoorEventActive */ + bool isTimeDoorEventActive() const; + + /** setTimeDoorEventActive */ + void setTimeDoorEventActive(); + + /** setTimeDoorEventInactive */ + void setTimeDoorEventInactive(); + + /** Sets status indicating it is effected by Timeshift */ + void setTimeEffected(); + + /** Sets status indicating it is not effected by Timeshift */ + void setTimeStatic(); + + /** Checks to see if the Front room exists(return) and has flags set(b) */ + bool checkFrontRoom(bool &b) const; + + /** Checks to see if the Back room exists(return) and has flags set(b) */ + bool checkBackRoom(bool &b) const; + + /** Checks to see if the Front and Back room exists(return) and has flags set(b) */ + bool checkRooms(bool &b) const; + + /** Transitions the game to the next room */ + void triggerExit(); + + /** TODO(Zeldex) Whats special about this? */ + bool isLeavingSealedTempleSideDoorPostSkyKeep() const; + + /** */ + void transitionPushRoomFlags() const; + + /** */ + void transitionPullRoomFlags() const; + + /** Checks a point to determine which side of the door it is on */ + bool isPositionInFrontOfDoor(const mVec3_c &point) const; + + /** Checks the players postion to see if it is front of the door. This means it will be pulled open */ + bool checkPullDoor() const; + + /** Checks to see if the door has a flow entry point */ + bool hasFlowEntryPoint(); + + /** Checks to see if the Door is effected by Timeshift */ + bool isTimeEffected() const; + + /** Sets the Position of the Doorknob based on the Animation */ + void setDoorKnobPosition(); + + /** Checks to see if the Player is within an interactable range */ + bool isPlayerInteractable() const; + + /** Checks to see if the Player is within an interactable range when door is locked */ + bool isPlayerInteractableLocked() const; + + /** Plays the talk event for when the door is locked */ + void playInteractionLocked(); + +public: + s32 getType() const { + return mParams & 0x3F; + } + s32 getField_0x5B4() const { + return mFrontRoomId; + } + s32 getField_0x5B5() const { + return mBackRoomId; + } + +public: // Functions in this section defined in main dol + bool isConnectedToOtherDoor() const; + dAcRef_c &getConnectedDoorRef(); // return mConnectedDoor; + + /** fn_80194C70 : Rotates the input by this->mRotation.y and adds this->mPosition */ + void stepTowards(mVec3_c &newPosition) const; + private: + /* 0x33C */ m3d::smdl_c mMdl0; + /* 0x358 */ m3d::smdl_c mMdl1; + /* 0x374 */ m3d::mdlAnmChr mAnmChr; + /* 0x3DC */ ActorEventRelated mEventRelated; + /* 0x42C */ dFlowMgr_c mFlowMgr; + /* 0x4E8 */ dEmitter_c mEmmiterL; + /* 0x51C */ dEmitter_c mEmmiterR; + /* 0x550 */ dTimeBits mTimeBits; + /* 0x554 */ dAcRef_c mConnectedDoor; ///< When the door is a double door, this is its pair + /* 0x560 */ dAcRef_c mLock; + /* 0x56C */ dAcRef_c mObjRef; ///< TODO(Zeldex) This is probably the Sandship stage for boss + + /* 0x578 */ mMtx_c mMtx; ///< Currently unknown. I am assuming this is used to move the door on the Sandship stage + ///< while the boat is rocking + + /* 0x5A8 */ u32 mFlags; ///< 0x2 - Time Effected + /* 0x5AC */ u32 mRumbleIdx; ///< Rumble used for when opening the main sealed temple door + /* 0x5B0 */ u8 mExitTimer; ///< Timer used to advance the Begin Pull/Push events + /* 0x5B1 */ u8 mLockBehavior; ///< see LockBehavior_e + /* 0x5B2 */ u8 mSceneflag; ///< Used for unlocking/locking the door. + /* 0x5B3 */ u8 mEventCallbackType; ///< 0 for events without callbacks, 1 for events with a callback + /* 0x5B4 */ s8 mFrontRoomId; ///< Room id of the front side of the door + /* 0x5B5 */ s8 mBackRoomId; ///< Room id of the back side of the door + /* 0x5B6 */ s8 mFramesInEvent; ///< The count of frames in one particular event + /* 0x5B7 */ bool mbDoubleDoor; ///< Set if the type was matched to be a double door variant + /* 0x5B8 */ bool mbSingleDoor; ///< UNUSHED - Set if the type was matched to be a single door + /* 0x5B9 */ bool mbInSandshipBoss; ///< Indicates if in the Tentalus fight + /* 0x5BA */ bool field_0x5BA; ///< ??? + /* 0x5BB */ bool mbKobunDoor; ///< Used to indicate its Cawlin and Strich's door }; #endif diff --git a/include/d/a/obj/d_a_obj_door_base.h b/include/d/a/obj/d_a_obj_door_base.h index 5cfc11105..9a64bf34c 100644 --- a/include/d/a/obj/d_a_obj_door_base.h +++ b/include/d/a/obj/d_a_obj_door_base.h @@ -1,11 +1,28 @@ #ifndef D_A_OBJ_DOOR_BASE_H #define D_A_OBJ_DOOR_BASE_H +#include "d/a/d_a_base.h" #include "d/a/obj/d_a_obj_base.h" +#include "f/f_list_mg.h" // Ghidra: ActorDoorBase // size: // non-official name -class dAcObjDoor_c : public dAcObjBase_c {}; +class dAcObjDoor_c : public dAcObjBase_c { +public: + dAcObjDoor_c(); + ~dAcObjDoor_c(); + + virtual bool canOpen() = 0; + virtual bool hasVisitedRoom(); + virtual void vt_0x88(); + virtual void vt_0x8C(); + +protected: + dAcRef_c mDoorRef; + +private: + static fLiMgBa_c sDoorList; +}; #endif diff --git a/include/d/a/obj/d_a_obj_door_boss.h b/include/d/a/obj/d_a_obj_door_boss.h index 945238a25..b4ef86024 100644 --- a/include/d/a/obj/d_a_obj_door_boss.h +++ b/include/d/a/obj/d_a_obj_door_boss.h @@ -10,6 +10,8 @@ class dAcOdoorBoss_c : public dAcObjDoor_c { dAcOdoorBoss_c() : mStateMgr(*this, sStateID::null) {} virtual ~dAcOdoorBoss_c() {} + virtual bool canOpen() override; + STATE_FUNC_DECLARE(dAcOdoorBoss_c, UnlockWait); STATE_FUNC_DECLARE(dAcOdoorBoss_c, CorrectKey); STATE_FUNC_DECLARE(dAcOdoorBoss_c, KeyInsertInitialInterval); diff --git a/include/d/a/obj/d_a_obj_fence.h b/include/d/a/obj/d_a_obj_fence.h index 720c41faa..8b7afd5d3 100644 --- a/include/d/a/obj/d_a_obj_fence.h +++ b/include/d/a/obj/d_a_obj_fence.h @@ -10,6 +10,15 @@ class dAcOFence_c : public dAcObjBase_c { dAcOFence_c(); virtual ~dAcOFence_c(); + bool fn_550_11B0() const; + void fn_550_1250(); + void fn_550_12B0(); + void fn_550_12C0(); + + void changeToRequestConfineEvent() { + mStateMgr.changeState(StateID_RequestConfineEvent); + } + STATE_FUNC_DECLARE(dAcOFence_c, WaitOpen); STATE_FUNC_DECLARE(dAcOFence_c, Open); STATE_FUNC_DECLARE(dAcOFence_c, OpenPocoAPoco); @@ -21,7 +30,8 @@ class dAcOFence_c : public dAcObjBase_c { STATE_FUNC_DECLARE(dAcOFence_c, RequestConfineEvent); private: - /* 0x??? */ STATE_MGR_DECLARE(dAcOFence_c); + /* 0x330 */ u8 _0x330[0x368 - 0x330]; + /* 0x368 */ STATE_MGR_DECLARE(dAcOFence_c); }; #endif diff --git a/include/d/a/obj/d_a_obj_lock.h b/include/d/a/obj/d_a_obj_lock.h index 4da6ba020..071bf5c53 100644 --- a/include/d/a/obj/d_a_obj_lock.h +++ b/include/d/a/obj/d_a_obj_lock.h @@ -12,8 +12,18 @@ class dAcOLock_c : public dAcObjBase_c { STATE_FUNC_DECLARE(dAcOLock_c, Wait); + bool checkField_0x2091() const { + return field_0x2091; + } + void setField_0x2090() { + field_0x2090 = true; + } + private: - /* 0x??? */ STATE_MGR_DECLARE(dAcOLock_c); + /* 0x???? */ STATE_MGR_DECLARE(dAcOLock_c); + /* 0x???? */ u8 _0x36C[0x2090 - 0x36C]; + /* 0x2090 */ bool field_0x2090; + /* 0x2091 */ bool field_0x2091; }; #endif diff --git a/include/d/a/obj/d_a_obj_shutter.h b/include/d/a/obj/d_a_obj_shutter.h index e2fa570a2..d33554c8d 100644 --- a/include/d/a/obj/d_a_obj_shutter.h +++ b/include/d/a/obj/d_a_obj_shutter.h @@ -10,6 +10,8 @@ class dAcOShutter_c : public dAcObjDoor_c { dAcOShutter_c() : mStateMgr(*this, sStateID::null) {} virtual ~dAcOShutter_c() {} + virtual bool canOpen() override; + STATE_FUNC_DECLARE(dAcOShutter_c, Wait); STATE_FUNC_DECLARE(dAcOShutter_c, Open); STATE_FUNC_DECLARE(dAcOShutter_c, Close); diff --git a/include/d/a/obj/d_a_obj_shutter_change_scene.h b/include/d/a/obj/d_a_obj_shutter_change_scene.h index 8479e7606..71a8b17fb 100644 --- a/include/d/a/obj/d_a_obj_shutter_change_scene.h +++ b/include/d/a/obj/d_a_obj_shutter_change_scene.h @@ -10,6 +10,8 @@ class dAcOShutterChangeScene_c : public dAcObjDoor_c { dAcOShutterChangeScene_c() : mStateMgr(*this, sStateID::null) {} virtual ~dAcOShutterChangeScene_c() {} + virtual bool canOpen() override; + STATE_FUNC_DECLARE(dAcOShutterChangeScene_c, WaitOpenShutter); STATE_FUNC_DECLARE(dAcOShutterChangeScene_c, WaitOpenShutterForEvent); STATE_FUNC_DECLARE(dAcOShutterChangeScene_c, OpenShutter); diff --git a/include/d/a/obj/d_a_obj_tr_shutter_cs.h b/include/d/a/obj/d_a_obj_tr_shutter_cs.h index f8b074fe9..7f2d150a5 100644 --- a/include/d/a/obj/d_a_obj_tr_shutter_cs.h +++ b/include/d/a/obj/d_a_obj_tr_shutter_cs.h @@ -10,6 +10,8 @@ class dAcOTrlyShtrChgScn_c : public dAcObjDoor_c { dAcOTrlyShtrChgScn_c() : mStateMgr(*this, sStateID::null) {} virtual ~dAcOTrlyShtrChgScn_c() {} + virtual bool canOpen() override; + STATE_FUNC_DECLARE(dAcOTrlyShtrChgScn_c, Wait); STATE_FUNC_DECLARE(dAcOTrlyShtrChgScn_c, OpenEvent); diff --git a/include/d/a/obj/d_a_obj_trolley_shutter.h b/include/d/a/obj/d_a_obj_trolley_shutter.h index 86ea3dad5..f7ed3c3cb 100644 --- a/include/d/a/obj/d_a_obj_trolley_shutter.h +++ b/include/d/a/obj/d_a_obj_trolley_shutter.h @@ -10,6 +10,8 @@ class dAcOTrolleyShutter_c : public dAcObjDoor_c { dAcOTrolleyShutter_c() : mStateMgr(*this, sStateID::null) {} virtual ~dAcOTrolleyShutter_c() {} + virtual bool canOpen() override; + STATE_FUNC_DECLARE(dAcOTrolleyShutter_c, Wait); STATE_FUNC_DECLARE(dAcOTrolleyShutter_c, OpenEvent); diff --git a/include/d/col/bg/d_bg_s_gnd_chk.h b/include/d/col/bg/d_bg_s_gnd_chk.h index f304c2a39..6b3e26961 100644 --- a/include/d/col/bg/d_bg_s_gnd_chk.h +++ b/include/d/col/bg/d_bg_s_gnd_chk.h @@ -27,6 +27,9 @@ class dBgS_ObjGndChk : public dBgS_GndChk { static dBgS_ObjGndChk &GetInstance() { return sInstance; } + static dBgS_ObjGndChk *GetPInstance() { + return &sInstance; + } static f32 GetGroundHeight() { return sGroundHeight; } diff --git a/include/d/d_player_act.h b/include/d/d_player_act.h index cf1c92364..f3eab389c 100644 --- a/include/d/d_player_act.h +++ b/include/d/d_player_act.h @@ -630,7 +630,7 @@ class daPlayerActBase_c : public daPlBase_c { bool isAttackingSpinHorizontal() const; bool isAttackingSpinVertical() const; void setBonkRelatedAnimFlag(bool b); - void setPosYRot(const mVec3_c &pos, mAng rot, bool force, UNKWORD, UNKWORD); + void setPosYRot(const mVec3_c &pos, mAng rot, bool force = false, UNKWORD = 0, UNKWORD = 0); void setTransform(const mMtx_c &mtx, bool force, UNKWORD, UNKWORD); bool someTargetedActorCheck() const; static mAng fn_8005BA90(); @@ -646,7 +646,6 @@ class daPlayerActBase_c : public daPlBase_c { static const char *getSwordName(s32); static s32 getCurrentlyEquippedShieldType(); - static const mColor &getEarringsColor(); static mVec3_c sPos1; diff --git a/include/d/d_room.h b/include/d/d_room.h index 287ae7c15..225b0bf1a 100644 --- a/include/d/d_room.h +++ b/include/d/d_room.h @@ -111,6 +111,9 @@ class dRoom_c : public dBase_c { bool checkFlag(u32 flag) { return mFlags & flag; } + void setFlag(u8 flag) { + mFlags |= flag; + } void drawOnMapIfVisible(mMtx_c *mtx, int param); void getBounds(mVec3_c *min, mVec3_c *max) const; diff --git a/include/d/d_stage.h b/include/d/d_stage.h index b0de4c981..3c3d2a93f 100644 --- a/include/d/d_stage.h +++ b/include/d/d_stage.h @@ -116,8 +116,10 @@ class dStage_c : public dBase_c { int draw() override; void deleteReady() override; + void fn_801B3C60(int roomId); void drawMap(mMtx_c *mtx, int); dRoom_c *getRoom(s32 idx); + void updateRoomFlags(int, int); void setRoom(int roomid, dRoom_c *room); void handleRoomChange(int roomid); diff --git a/include/d/d_stage_mgr.h b/include/d/d_stage_mgr.h index 68d47f3f1..f7a004050 100644 --- a/include/d/d_stage_mgr.h +++ b/include/d/d_stage_mgr.h @@ -106,7 +106,6 @@ class dStageMgr_c : public dBase_c { static dStageMgr_c *GetInstance() { return sInstance; } - EGG::CpuTexture *getField_0x8898() { return field_0x8898; } @@ -225,7 +224,7 @@ class dStageMgr_c : public dBase_c { // ... u8 ___[438]; /* 0x8898 */ EGG::CpuTexture *field_0x8898; - + u8 _0x889C[4]; /* 0x88A0 */ u32 field_0x88A0; diff --git a/include/toBeSorted/actor_event.h b/include/toBeSorted/actor_event.h index 03fd30d61..cbd684226 100644 --- a/include/toBeSorted/actor_event.h +++ b/include/toBeSorted/actor_event.h @@ -18,6 +18,7 @@ class ActorEventRelated { bool isAdvance(); int getSomeEventRelatedNumber(); + int getSingleShortData(int *result, u32 code, u32); int getSingleIntData(int *result, u32 code, u32); int getSingleFloatData(f32 *result, u32 code, u32); int getSingleVecData(mVec3_c *result, u32 code, u32); diff --git a/include/toBeSorted/event_manager.h b/include/toBeSorted/event_manager.h index 1b89074f9..3f3946ab1 100644 --- a/include/toBeSorted/event_manager.h +++ b/include/toBeSorted/event_manager.h @@ -11,6 +11,7 @@ class dAcObjBase_c; class EventManager { public: + static bool setEvent(dAcBase_c *actor, Event *, dAcBase_c *); static bool isInEvent(dAcBase_c *actor, const char *eventName); static bool finishEvent(dAcBase_c *actor, const char *eventName); static void changeOwnEvent(dAcBase_c *actor1, dAcBase_c *actor2, Event *event, UNKWORD); diff --git a/src/REL/d/a/obj/d_a_obj_door.cpp b/src/REL/d/a/obj/d_a_obj_door.cpp index 3f172d1f8..a0a442b02 100644 --- a/src/REL/d/a/obj/d_a_obj_door.cpp +++ b/src/REL/d/a/obj/d_a_obj_door.cpp @@ -1,3 +1,1801 @@ #include "d/a/obj/d_a_obj_door.h" +#include "c/c_lib.h" +#include "common.h" +#include "d/a/d_a_base.h" +#include "d/a/d_a_item.h" +#include "d/a/d_a_player.h" +#include "d/a/obj/d_a_obj_base.h" +#include "d/a/obj/d_a_obj_fence.h" +#include "d/a/obj/d_a_obj_lock.h" +#include "d/col/bg/d_bg_s.h" +#include "d/col/bg/d_bg_s_gnd_chk.h" +#include "d/col/c/c_m3d_g_aab.h" +#include "d/d_room.h" +#include "d/d_rumble.h" +#include "d/d_sc_game.h" +#include "d/d_stage.h" +#include "d/d_stage_mgr.h" +#include "d/flag/sceneflag_manager.h" +#include "d/flag/storyflag_manager.h" +#include "d/snd/d_snd_wzsound.h" +#include "egg/math/eggMath.h" +#include "f/f_base.h" +#include "f/f_manager.h" +#include "f/f_profile_name.h" +#include "m/m3d/m_anmmdl.h" +#include "m/m3d/m_fanm.h" +#include "m/m_mtx.h" +#include "m/m_vec.h" +#include "nw4r/g3d/res/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resmdl.h" +#include "nw4r/math/math_arithmetic.h" +#include "s/s_Math.h" +#include "sized_string.h" +#include "toBeSorted/attention.h" +#include "toBeSorted/d_emitter.h" +#include "toBeSorted/event.h" +#include "toBeSorted/event_manager.h" + SPECIAL_ACTOR_PROFILE(OBJ_DOOR, dAcOdoor_c, fProfile::OBJ_DOOR, 0x188, 0, 7); + +namespace { + +const char *const DoorAnim = "DoorAnim"; +const char *const DoorAnim_ = "DoorAnim"; +const char *const DoorAnimPull = "DoorAnimPull"; +const char *const DoorAnimPush = "DoorAnimPush"; + +struct DoorFileMapping { + const dAcOdoor_c::Subtype_e mType; + const char *mResName; + const char *mMdlName; +}; +DoorFileMapping sDoorMappings[8] = { + { dAcOdoor_c::DOOR_NORMAL, "DoorA00", "DoorA00"}, + { dAcOdoor_c::DOOR_METAL, "DoorA01", "DoorA01"}, + { dAcOdoor_c::DOOR_BATREAUX, "DoorA02", "DoorA02"}, + { dAcOdoor_c::DOOR_TEMPLE_SIDE, "DoorB00", "DoorB00"}, + { dAcOdoor_c::DOOR_DOUBLE, "DoorC00", "DoorC00"}, + { dAcOdoor_c::DOOR_DOUBLE_OUTSIDE, "DoorC01", "DoorC01"}, + {dAcOdoor_c::DOOR_SANDSEA_TIMESHIFT, "DoorE", "DoorE_T"}, + { dAcOdoor_c::DOOR_SPARRING_HALL, "DoorH", "DoorH"}, +}; + +const char *const DoorF = "DoorF"; +const char *const DoorF_ = "DoorF"; +const char *const DoorF_Open = "DoorF_Open"; +const char *const DoorF_Close = "DoorF_Close"; + +static const u8 sDoorCallbackTypeMap[2] = { + 0, // Doesnt have callbacks + 1 // Has Callbacks +}; + +const dAcOdoor_c::Subtype_e sDoubleDoorTypes[5] = { + sDoorMappings[3].mType, // dAcOdoor_c::DOOR_TEMPLE_SIDE + sDoorMappings[4].mType, // dAcOdoor_c::DOOR_DOUBLE + sDoorMappings[5].mType, // dAcOdoor_c::DOOR_DOUBLE_OUTSIDE + sDoorMappings[6].mType, // dAcOdoor_c::DOOR_SANDSEA_TIMESHIFT + sDoorMappings[7].mType, // dAcOdoor_c::DOOR_SPARRING_HALL +}; + +const char *const DoorPull = "DoorPull"; +const char *const DoorPush = "DoorPush"; +const char *const DoorPullLock = "DoorPullLock"; +const char *const DoorPushLock = "DoorPushLock"; +const char *const DoorTalk = "DoorTalk"; + +bool getDoorMapping(u32 type, const DoorFileMapping *&filemap) { + bool found = false; + int i = 0; + while (!found && i <= (int)ARRAY_LENGTH(sDoorMappings) - 1) { + if (sDoorMappings[i].mType == type) { + found = true; + } else { + i++; + } + } + + if (found) { + filemap = &sDoorMappings[i]; + } + + return found; +} + +bool getDoorResName(u32 type, const char *&name) { + const DoorFileMapping *filemap = nullptr; + bool found = getDoorMapping(type, filemap); + if (found) { + name = filemap->mResName; + } + return found; +} + +bool getDoorMdlName(u32 type, const char *&name) { + const DoorFileMapping *filemap = nullptr; + bool found = getDoorMapping(type, filemap); + if (found) { + name = filemap->mMdlName; + } + return found; +} + +bool getDoorCallbackTypeMapped(u8 search, u8 &idx) { + bool found = false; + int i = 0; + while (!found && i <= (int)ARRAY_LENGTH(sDoorCallbackTypeMap) - 1) { + if (sDoorCallbackTypeMap[i] == search) { + found = true; + } else { + i++; + } + } + + if (found) { + idx = i; + } + + return found; +} + +bool isDoubleDoorType(s32 type) { + bool found = false; + int i = 0; + while (!found && i <= (int)ARRAY_LENGTH(sDoubleDoorTypes) - 1) { + if (sDoubleDoorTypes[i] == type) { + found = true; + } else { + i++; + } + } + + return found; +} +const char *getDoorInteractionName() { + return DoorTalk; +} + +const char *const sSandShipBossStages[2] = {"B301", "D301_1"}; +bool isInSandshipBoss() { + bool found = true; + int i = 0; + while (found && i <= (int)ARRAY_LENGTH(sSandShipBossStages) - 1) { + if (dScGame_c::isCurrentStage(sSandShipBossStages[i])) { + found = false; + } else { + i++; + } + } + + return !found; +} + +bool isInEvent(const char *eventName) { + return strequals(EventManager::getCurrentEventName(), eventName); +} + +const char *const sTimeDoorEventNames[2] = { + "TimeDoorIn", + "TimeDoorOut", +}; + +bool isInTimeDoorEvent() { + int i = 0; + bool found = true; + while (found && i <= (int)ARRAY_LENGTH(sTimeDoorEventNames) - 1) { + if (isInEvent(sTimeDoorEventNames[i])) { + found = false; + } else { + i++; + } + } + return !found; +} + +bool checkRoom(s8 roomID, bool &b) { + dRoom_c *pRoom = dStage_c::GetInstance()->getRoom(roomID); + if (pRoom == nullptr) { + return false; + } + + b = pRoom->checkFlag(0x1E) != 0; + return true; +} + +} // namespace + +void rodata0() { + const f32 a[] = {0.f, 16.f, 60.f, 0.f, 80.f, 100.f, 0.f, 160.f, 100.f}; + const u32 b[] = {0x2D2D7832, 0x73010000, 0x03000000}; +} +static mVec3_c sDoorknobOffset0(70.f, 0.f, 0.f); +static mVec3_c sDoorknobOffset1(52.f, 110.f, 0.f); + +static mVec3_c sVec2(0.f, 0.f, 70.f); +static mVec3_c sVec3(0.f, 0.f, -70.f); + +static const InteractionTargetDef sOpenInteraction = { + 0, 2, 1, OPEN, 0, 1000.f, 60.f, 0.f, -100.f, 100.f, 50.f, 1.f, +}; +static const InteractionTargetDef sLockedInteraction = { + 0, 2, 1, EXAMINE_TALK, 0, 1000.f, 60.f, 0.f, -100.f, 100.f, 50.f, 1.f, +}; +void rodata1() { + const f32 a[] = {200.f, 0.f}; +} + +SizedString<32> sStageF402("F402"); + +bool dAcOdoor_c::createHeap() { + s32 type = getFromParams(0, 0x3F); + if (type == DOOR_TEMPLE_MAIN) { + nw4r::g3d::ResFile resFile(getOarcResFile(DoorF)); + if (!resFile.IsValid()) { + return false; + } + mAnmChr.create(resFile.ptr(), DoorF_, DoorF_Open, &mAllocator, 0x120); + } else { + nw4r::g3d::ResFile resFileAnim(getOarcResFile(DoorAnim)); + if (!resFileAnim.IsValid()) { + return false; + } + if (!mAnmChr.create(resFileAnim.ptr(), DoorAnim_, DoorAnimPull, &mAllocator, 0)) { + return false; + } + + const char *resFileName = nullptr; + getDoorResName(type, resFileName); + if (resFileName == nullptr) { + return false; + } + + nw4r::g3d::ResFile resFileMdl(getOarcResFile(resFileName)); + if (!resFileMdl.IsValid()) { + return false; + } + + const char *resMdlName = nullptr; + getDoorMdlName(type, resMdlName); + if (resMdlName == nullptr) { + return false; + } + + nw4r::g3d::ResMdl resMdl = resFileMdl.GetResMdl(resMdlName); + if (!resMdl.IsValid()) { + return false; + } + + if (!mMdl0.create(resMdl, &mAllocator, 0x120, 1, nullptr)) { + return false; + } + + if (isTimeEffected()) { + nw4r::g3d::ResMdl resMdl = resFileMdl.GetResMdl("DoorE_N"); + if (!resMdl.IsValid()) { + return false; + } + + if (!mMdl1.create(resMdl, &mAllocator, 0x120, 1, nullptr)) { + return false; + } + } + } + + return true; +} + +int dAcOdoor_c::actorCreate() { + // NONMATCHING - Regalloc issues + s32 subtype = getType(); + setSubtype(subtype); + changeLoadedEntitiesWithSet(); + + if (subtype == DOOR_SANDSEA_TIMESHIFT && + !(dScGame_c::isCurrentStage("B301") || dScGame_c::isCurrentStage("D301_1"))) { + setTimeEffected(); + } else { + setTimeStatic(); + } + + CREATE_ALLOCATOR(dAcOdoor_c); + + mSceneflag = getSceneflag(); + + if (getLockParameter() == LOCK_KEY) { + if (mSceneflag < 0xFF && !SceneflagManager::sInstance->checkBoolFlag(mRoomID, mSceneflag)) { + mLock.link( + static_cast( + create(this, fProfile::OBJ_SHUTTER_LOCK, 0, nullptr, nullptr, nullptr, 0, 0x3F) + ) + ); + } + } else { + u8 type = getLockBehavior(); + if (type <= LOCK_NIGHT) { + mLockBehavior = type; + } else { + mLockBehavior = LOCK_NEVER; + } + } + + u8 callbackType; + if (!getDoorCallbackTypeMapped(getDoorCallbackType(), callbackType)) { + callbackType = 0; // Default to no callback + } + setEventCallbackType(callbackType); + + setFrontRoom(getFrontRoomParam()); + setBackRoom(getBackRoomParam()); + + mRotation.z = mAng(0); + mRotation.x = mAng(0); + { + s32 roomId = mRoomID; + addActorToRoom(-1); + setRoomId(roomId); + } + + if (isDoubleDoorType(subtype)) { + setDoubleDoor(); + } else { + setNotDoubleDoor(); + } + + if (getType() == DOOR_TEMPLE_MAIN) { + mAnmChr.setAnm(DoorF_Open, m3d::PLAY_MODE_4, 0.f); + mAnmChr.setFrame(mAnmChr.getAnm().getStartFrame()); + mAnmChr.getModel().setPriorityDraw(0x1C, 0); + } else { + mAnmChr.setAnm(DoorAnimPull, m3d::PLAY_MODE_4, 0.f); + mAnmChr.setFrame(mAnmChr.getAnm().getStartFrame()); + if (isTimeEffected()) { + mMdl0.setPriorityDraw(0xF, 0); + mMdl1.setPriorityDraw(0xB, 0); + } else { + mMdl0.setPriorityDraw(0x1C, 0); + } + } + + bool inAcademy = dScGame_c::isCurrentStage("F001r"); + if (inAcademy) { + inAcademy = mVec3_c(1832.5f, 0.f, -1978.0f).squareDistanceToXZ(mPosition) < 100.f; + } + mbKobunDoor = inAcademy; + + return SUCCEEDED; +} + +extern "C" void fn_80067290(dTimeBits *pBits, s32 roomId, const mVec3_c &pos, f32); + +int dAcOdoor_c::actorPostCreate() { + if (mbDoubleDoor) { + if (!isConnectedToOtherDoor()) { + bool foundPair = false; + dAcOdoor_c *pDoor = + static_cast(fManager_c::searchBaseByProfName(fProfile::OBJ_DOOR, nullptr)); + while (!foundPair && pDoor != nullptr) { + if (mID != pDoor->mID && pDoor->mbDoubleDoor && !pDoor->isConnectedToOtherDoor() && + mPosition.squareDistance(pDoor->mPosition) < 40000.f) { + foundPair = true; + this->getConnectedDoorRef().link(pDoor); + pDoor->getConnectedDoorRef().link(this); + + // Not really sure the point of this + // How does this prevent Door ordering issues + // This may be why the field goes unused? + if (getLockParameter() == LOCK_KEY) { + this->setSingleDoor(); + pDoor->setNotSingleDoor(); + } else { + this->setNotSingleDoor(); + pDoor->setSingleDoor(); + } + } + pDoor = static_cast(fManager_c::searchBaseByProfName(fProfile::OBJ_DOOR, pDoor)); + } + + if (!foundPair) { + setSingleDoor(); + } + } + } else { + setSingleDoor(); + } + + mVec3_c pos = mPosition + mVec3_c::Ey * 10.f; + bool gndChk = dBgS_ObjGndChk::CheckPos(pos); + dBgS_ObjGndChk *objGndCheck = dBgS_ObjGndChk::GetPInstance(); + if (gndChk) { + mLightingInfo.mLightingCode = dBgS_ObjGndChk::GetLightingCode(); + if (objGndCheck != nullptr) { + setPolyAttrs(*objGndCheck); + } + } + + if (isInSandshipBoss()) { + setInSandshipBoss(); + unsetActorProperty(AC_PROP_0x1); + + if (gndChk) { + dBgS *pBgS = dBgS::GetInstance(); + if (pBgS != nullptr && objGndCheck != nullptr) { + const dAcObjBase_c *pObj = pBgS->GetActorPointer(*objGndCheck); + if (pObj) { + mObjRef.link(const_cast(pObj)); + mVec3_c v(mPosition.x, dBgS_ObjGndChk::GetGroundHeight(), mPosition.z); + v -= pObj->mPosition; + + v.rotY(-pObj->mRotation.y); + + mAng rotY = mRotation.y - pObj->mRotation.y; + mMtx.transS(v); + mMtx.YrotM(rotY); + } + } + } + } + + if (!mObjRef.isLinked()) { + s32 type = getType(); + updateMatrix(); + mAnmChr.getModel().setLocalMtx(mWorldMtx); + mAnmChr.getModel().calc(false); + + if (type != DOOR_TEMPLE_MAIN) { + mMtx_c m; + mAnmChr.getModel().getNodeWorldMtx(1, m); + m.transM(sDoorknobOffset0); + mMdl0.setLocalMtx(m); + if (isTimeEffected()) { + mMdl1.setLocalMtx(m); + } + } + + dAcOLock_c *pLock = mLock.get(); + if (pLock == nullptr) { + setDoorKnobPosition(); + } else { + mPositionCopy2.set(pLock->mPosition); + mPositionCopy3.set(pLock->mPosition); + } + + mVec3_c min, max; + min.set(999999.f, 999999.f, 999999.f); + max.set(-999999.f, -999999.f, -999999.f); + + if (type == DOOR_TEMPLE_MAIN) { + mAnmChr.getModel().getBounds(&min, &max); + } else { + mVec3_c min_l, max_l; + mMtx_c local; + mMdl0.getBounds(&min_l, &max_l); + mMdl0.getLocalMtx(local); + + mMtx_c world = mWorldMtx; + world.inverse(); + + mVec3_c minPos = min_l; + local.multVec(minPos, minPos); + world.multVec(minPos, minPos); + + // clang-format off + min.set( + nw4r::ut::Min(minPos.x, min.x), + nw4r::ut::Min(minPos.y, min.y), + nw4r::ut::Min(minPos.z, min.z) + ); + max.set( + nw4r::ut::Max(minPos.x, max.x), + nw4r::ut::Max(minPos.y, max.y), + nw4r::ut::Max(minPos.z, max.z) + ); + // clang-format on + + mVec3_c maxPos = max_l; + local.multVec(maxPos, maxPos); + world.multVec(maxPos, maxPos); + // clang-format off + min.set( + nw4r::ut::Min(maxPos.x, min.x), + nw4r::ut::Min(maxPos.y, min.y), + nw4r::ut::Min(maxPos.z, min.z) + ); + max.set( + nw4r::ut::Max(maxPos.x, max.x), + nw4r::ut::Max(maxPos.y, max.y), + nw4r::ut::Max(maxPos.z, max.z) + ); + // clang-format on + + mVec3_c vecs[6] = { + mVec3_c(min_l.x, min_l.y, max_l.z), mVec3_c(min_l.x, max_l.y, min_l.z), + mVec3_c(min_l.x, max_l.y, max_l.z), mVec3_c(max_l.x, min_l.y, min_l.z), + mVec3_c(max_l.x, min_l.y, max_l.z), mVec3_c(max_l.x, max_l.y, min_l.z), + }; + + for (int i = 0, j = 0; i < (int)ARRAY_LENGTH(vecs); i++, j++) { + local.multVec(vecs[i], vecs[j]); + world.multVec(vecs[i], vecs[j]); + // clang-format off + min.set( + nw4r::ut::Min(vecs[j].x, min.x), + nw4r::ut::Min(vecs[j].y, min.y), + nw4r::ut::Min(vecs[j].z, min.z) + ); + max.set( + nw4r::ut::Max(vecs[j].x, max.x), + nw4r::ut::Max(vecs[j].y, max.y), + nw4r::ut::Max(vecs[j].z, max.z) + ); + // clang-format on + } + } + mBoundingBox.Set(min, max); + } + + if (isTimeEffected()) { + fn_80067290(&mTimeBits, mRoomID, mPosition, 200.f); + } + + mCullingDistance = EGG::Math::maxNumber(); + + return SUCCEEDED; +} + +int dAcOdoor_c::doDelete() { + changeLoadedEntitiesNoSet(); + return SUCCEEDED; +} + +int dAcOdoor_c::actorExecuteInEvent() { + if (isTimeEffected()) { + fn_80067290(&mTimeBits, mRoomID, mPosition, 200.f); + } + + if (mEventRelated.isAdvance()) { + mFramesInEvent = 0; + } else if (mFramesInEvent < 0xFF) { + mFramesInEvent++; + } + + if (isTimeDoorEventActive()) { + setObjectProperty(OBJ_PROP_0x200); + return SUCCEEDED; + } + + switch (mEventCallbackType) { + case 0: { + bool b; + checkRoom(mRoomID, b); + if (b) { + setObjectProperty(OBJ_PROP_0x200); + return SUCCEEDED; + } + } break; + case 1: { + bool b; + checkRooms(b); + if (b) { + setObjectProperty(OBJ_PROP_0x200); + return SUCCEEDED; + } + } break; + } + + unsetObjectProperty(OBJ_PROP_0x200); + s32 type = getType(); + + static mVec3_c v1(0.f, 0.f, 70.f); + static mVec3_c v2(0.f, 0.f, -70.f); + + f32 frame0 = -1.f; + f32 frame1 = -1.f; + + switch (mEventRelated.getCurrentEventCommand()) { + case 'pllB': { + f32 frame = dAcPy_c::GetLink()->getCurrentAnimFrame(); + if (mEventRelated.isAdvance()) { + mAnmChr.setAnm(DoorAnimPull, m3d::PLAY_MODE_4); + mAnmChr.setFrame(frame); + mExitTimer = 45; + + frame0 = frame; + if (mEventCallbackType == s8(1)) { + transitionPullRoomFlags(); + } + } else { + frame0 = mAnmChr.getAnm().getFrame(); + } + mAnmChr.setFrame(frame); + frame1 = mAnmChr.getAnm().getFrame(); + bool old_time = 0 == mExitTimer; + bool new_time = 0 == sLib::calcTimer(&mExitTimer); + switch (mEventCallbackType) { + case 0: { + if (!old_time && new_time) { + triggerExit(); + } + } break; + case 1: { + if (new_time) { + mEventRelated.advanceNext(); + } + } break; + } + } break; + case 'pllE': { + bool isStop; + const dAcPy_c *pPlayer = dAcPy_c::GetLink(); + f32 frame = pPlayer->getCurrentAnimFrame(); + if (mEventRelated.isAdvance()) { + isStop = false; + switch (mEventCallbackType) { + case 0: { + frame0 = frame; + } break; + case 1: { + frame0 = mAnmChr.getAnm().getFrame(); + } break; + } + mAnmChr.setAnm(DoorAnimPull, m3d::PLAY_MODE_4); + mAnmChr.setFrame(frame); + } else { + isStop = mAnmChr.getAnm().isStop(); + frame0 = mAnmChr.getAnm().getFrame(); + + if (!isStop) { + mAnmChr.setFrame(frame); + } + } + bool postStop = mAnmChr.getAnm().isStop(); + frame1 = mAnmChr.getAnm().getFrame(); + if (!isStop && postStop) { + if (mEventCallbackType == 1 && getField_0x5B4() != getField_0x5B5()) { + dRoom_c *pRoom = dStage_c::GetInstance()->getRoom(getField_0x5B4()); + if (pRoom != nullptr) { + pRoom->setFlag(0x4); + dStage_c::GetInstance()->fn_801B3C60(getField_0x5B5()); + } + } + mEventRelated.advanceNext(); + + bool search = true; + dAcOFence_c *pFence = + static_cast(fManager_c::searchBaseByProfName(fProfile::OBJ_FENCE, nullptr)); + while (search && pFence != nullptr) { + if (mAng::abs(pPlayer->mRotation.y - pFence->mRotation.y) < 0x4000) { + const mVec3_c &posFence = pFence->mPosition; + const mVec3_c &position = mPosition; + if (posFence.squareDistanceToXZ(position) < 22500.f && + nw4r::math::FAbs(posFence.y - position.y) < 500.f) { + search = false; + continue; + } + } + pFence = static_cast(fManager_c::searchBaseByProfName(fProfile::OBJ_FENCE, pFence)); + } + + if (!search) { + if (pFence->fn_550_11B0()) { + pFence->changeToRequestConfineEvent(); + } + pFence->fn_550_12C0(); + } + + if (mLock.get() != nullptr) { + mLock.get()->deleteRequest(); + } + } + } break; + case 'pshB': { + f32 frame = dAcPy_c::GetLink()->getCurrentAnimFrame(); + if (mEventRelated.isAdvance()) { + if (type == DOOR_TEMPLE_MAIN) { + mAnmChr.setAnm(DoorF_Open, m3d::PLAY_MODE_4); + mExitTimer = 120; + } else { + mAnmChr.setAnm(DoorAnimPush, m3d::PLAY_MODE_4); + mExitTimer = 45; + } + if (mEventCallbackType == s8(1)) { + transitionPushRoomFlags(); + } + frame0 = frame; + } else { + frame0 = mAnmChr.getAnm().getFrame(); + } + mAnmChr.setFrame(frame); + frame1 = mAnmChr.getAnm().getFrame(); + bool old_time = 0 == mExitTimer; + bool new_time = 0 == sLib::calcTimer(&mExitTimer); + switch (mEventCallbackType) { + case 0: { + if (!old_time && new_time) { + triggerExit(); + } + } break; + case 1: { + if (new_time) { + mEventRelated.advanceNext(); + } + } break; + } + } break; + case 'pshE': { + bool isStop; + f32 frame = dAcPy_c::GetLink()->getCurrentAnimFrame(); + if (mEventRelated.isAdvance()) { + isStop = false; + switch (mEventCallbackType) { + case 0: { + frame0 = frame; + } break; + case 1: { + frame0 = mAnmChr.getAnm().getFrame(); + } break; + } + if (type == DOOR_TEMPLE_MAIN) { + mAnmChr.setAnm(DoorF_Close, m3d::PLAY_MODE_4); + } else { + mAnmChr.setAnm(DoorAnimPush, m3d::PLAY_MODE_4); + } + mAnmChr.setFrame(frame); + } else { + isStop = mAnmChr.getAnm().isStop(); + frame0 = mAnmChr.getAnm().getFrame(); + if (!isStop) { + mAnmChr.setFrame(frame); + } + } + bool stop = mAnmChr.getAnm().isStop(); + frame1 = mAnmChr.getAnm().getFrame(); + if (!isStop && stop) { + if (mEventCallbackType == 1 && getField_0x5B4() != getField_0x5B5()) { + dRoom_c *pRoom = dStage_c::GetInstance()->getRoom(getField_0x5B5()); + if (pRoom != nullptr) { + pRoom->setFlag(0x4); + dStage_c::GetInstance()->fn_801B3C60(getField_0x5B4()); + } + } + mEventRelated.advanceNext(); + + bool search = true; + const dAcPy_c *pPlayer = dAcPy_c::GetLink(); + dAcOFence_c *pFence = + static_cast(fManager_c::searchBaseByProfName(fProfile::OBJ_FENCE, nullptr)); + while (search && pFence != nullptr) { + if (mAng::abs(pPlayer->mRotation.y - pFence->mRotation.y) < 0x4000) { + const mVec3_c &posFence = pFence->mPosition; + const mVec3_c &position = mPosition; + if (posFence.squareDistanceToXZ(position) < 22500.f && + nw4r::math::FAbs(posFence.y - position.y) < 500.f) { + search = false; + continue; + } + } + pFence = static_cast(fManager_c::searchBaseByProfName(fProfile::OBJ_FENCE, pFence)); + } + + if (!search) { + if (pFence->fn_550_11B0()) { + pFence->changeToRequestConfineEvent(); + } + pFence->fn_550_12C0(); + } + + if (mLock.get() != nullptr) { + mLock.get()->deleteRequest(); + } + } + if (type == DOOR_TEMPLE_MAIN) { + bool b; + if (frame0 == frame1) { + b = frame0 == 55.f; + } else { + b = frame0 < 55.f && 55.f <= frame1; + } + if (b) { + dRumble_c::start(dRumble_c::sRumblePreset5, dRumble_c::FLAG_SLOT0); + } + } + } break; + case 'wait': { + mEventRelated.advanceNext(); + } break; + case 'tktn': { + mEventRelated.advanceNext(); + } break; + case 'tkwt': { + mEventRelated.advanceNext(); + } break; + case 'tked': { + mEventRelated.advanceNext(); + } break; + case 'cAna': { + mVec3_c pos; + mAng rot; + if (type == DOOR_TEMPLE_MAIN) { + pos.set(0.f, 0.f, 85.f); + rot = mAng(0x8000); + rot += mRotation.y; + } else { + int dir; + mEventRelated.getSingleShortData(&dir, 'dir ', 0); + if (dir == 0) { + pos.set(v1); + rot = mAng(0x8000); + rot += mRotation.y; + } else { + pos.set(v2); + rot = mRotation.y; + } + } + stepTowards(pos); + dAcPy_c *pPlayer = dAcPy_c::GetLinkM(); + + if (mFramesInEvent > 30) { + pPlayer->setPosYRot(pos, rot); + mEventRelated.advanceNext(); + } else { + mVec3_c tmp = pPlayer->mPosition; + cLib::addCalcPos(&tmp, pos, 0.25f, 200.f, 0.f); + + mAng ang = pPlayer->mRotation.y; + sLib::addCalcAngle(ang.ref(), rot, 4, 0x7FFF, 0); + + if (pos.squareDistanceToXZ(tmp) < 25.f && mAng::abs(ang - mAng((s32)rot)) < 182) { + pPlayer->setPosYRot(pos, rot); + mEventRelated.advanceNext(); + } else { + pPlayer->setPosYRot(tmp, ang); + } + } + } break; + case 'cDeg': { + mVec3_c pos; + mAng rot; + if (mEventRelated.isAdvance()) { + if (type == DOOR_TEMPLE_MAIN) { + pos.set(0.f, 0.f, 90.f); + rot = mRotation.y; + } else { + int dir; + mEventRelated.getSingleShortData(&dir, 'dir ', 0); + if (dir == 0) { + pos.set(v1); + rot = mRotation.y - 0x8000; + } else { + pos.set(v2); + rot = mRotation.y; + } + } + stepTowards(pos); + dAcPy_c *pPlayer = dAcPy_c::GetLinkM(); + pPlayer->setPosYRot(pos, rot); + mEventRelated.advanceNext(); + } + } break; + case 'talk': + case 'lock': { + if (mEventRelated.isAdvance()) { + // Gets the message to show when the door is locked and is failed to be opened + s32 flow = mLock.get() == nullptr ? mParams >> 16 : 4001; + s32 part2 = flow < 10000U ? 1000 : 100; + s32 truncate = (flow / part2); + + u16 lower = flow - truncate * part2; + + s32 part1 = flow < 10000U ? 1000 : 100; + u16 upper = flow / part1; + mFlowMgr.triggerEntryPoint(upper, lower, 0, 0); + } + if (mFlowMgr.checkFinished()) { + mEventRelated.advanceNext(); + } + } break; + case 'unlk': { + dAcOLock_c *pLock = mLock.get(); + if (pLock == nullptr) { + mEventRelated.advanceNext(); + } else { + if (mEventRelated.isAdvance()) { + pLock->setField_0x2090(); + setDoorKnobPosition(); + } + if (pLock->checkField_0x2091()) { + mEventRelated.advanceNext(); + } + } + } break; + default: { + mEventRelated.advanceNext(); + } + case '????': { + } break; + } + + dAcObjBase_c *pObj = mObjRef.get(); + if (pObj != nullptr) { + mMtx_c m = pObj->mWorldMtx; + m += mMtx; + mWorldMtx = m; + mAnmChr.getModel().setLocalMtx(mWorldMtx); + } + + mAnmChr.getModel().calc(false); + + if (type != DOOR_TEMPLE_MAIN) { + mMtx_c nodeMtx; + mAnmChr.getModel().getNodeWorldMtx(1, nodeMtx); + nodeMtx.transM(sDoorknobOffset0); + mMdl0.setLocalMtx(nodeMtx); + if (isTimeEffected()) { + mMdl1.setLocalMtx(nodeMtx); + } + } + + if (pObj != nullptr) { + mVec3_c min, max; + min.set(999999.f, 999999.f, 999999.f); + max.set(-999999.f, -999999.f, -999999.f); + + if (type == DOOR_TEMPLE_MAIN) { + mAnmChr.getModel().getBounds(&min, &max); + } else { + mVec3_c min_l, max_l; + mMtx_c local; + mMdl0.getBounds(&min_l, &max_l); + mMdl0.getLocalMtx(local); + + mMtx_c world = mWorldMtx; + world.inverse(); + + mVec3_c minPos = min_l; + local.multVec(minPos, minPos); + world.multVec(minPos, minPos); + + // clang-format off + min.set( + nw4r::ut::Min(minPos.x, min.x), + nw4r::ut::Min(minPos.y, min.y), + nw4r::ut::Min(minPos.z, min.z) + ); + max.set( + nw4r::ut::Max(minPos.x, max.x), + nw4r::ut::Max(minPos.y, max.y), + nw4r::ut::Max(minPos.z, max.z) + ); + // clang-format on + + mVec3_c maxPos = max_l; + local.multVec(maxPos, maxPos); + world.multVec(maxPos, maxPos); + // clang-format off + min.set( + nw4r::ut::Min(maxPos.x, min.x), + nw4r::ut::Min(maxPos.y, min.y), + nw4r::ut::Min(maxPos.z, min.z) + ); + max.set( + nw4r::ut::Max(maxPos.x, max.x), + nw4r::ut::Max(maxPos.y, max.y), + nw4r::ut::Max(maxPos.z, max.z) + ); + // clang-format on + + mVec3_c vecs[6] = { + mVec3_c(min_l.x, min_l.y, max_l.z), mVec3_c(min_l.x, max_l.y, min_l.z), + mVec3_c(min_l.x, max_l.y, max_l.z), mVec3_c(max_l.x, min_l.y, min_l.z), + mVec3_c(max_l.x, min_l.y, max_l.z), mVec3_c(max_l.x, max_l.y, min_l.z), + }; + + for (int i = 0, j = 0; i < (int)ARRAY_LENGTH(vecs); j++, i++) { + local.multVec(vecs[i], vecs[j]); + world.multVec(vecs[i], vecs[j]); + // clang-format off + min.set( + nw4r::ut::Min(vecs[j].x, min.x), + nw4r::ut::Min(vecs[j].y, min.y), + nw4r::ut::Min(vecs[j].z, min.z) + ); + max.set( + nw4r::ut::Max(vecs[j].x, max.x), + nw4r::ut::Max(vecs[j].y, max.y), + nw4r::ut::Max(vecs[j].z, max.z) + ); + // clang-format on + } + } + mBoundingBox.Set(min, max); + } + + if (mEmmiterL.hasEmitters()) { + int node = mAnmChr.getModel().getNodeID("DoorF_L"); + if (node >= 0) { + mMtx_c nodeMtx; + mAnmChr.getModel().getNodeWorldMtx(node, nodeMtx); + mEmmiterL.setTransform(nodeMtx); + } + } + if (mEmmiterR.hasEmitters()) { + int node = mAnmChr.getModel().getNodeID("DoorF_R"); + if (node >= 0) { + mMtx_c nodeMtx; + mAnmChr.getModel().getNodeWorldMtx(node, nodeMtx); + mEmmiterR.setTransform(nodeMtx); + } + } + + switch (mEventRelated.getCurrentEventCommand()) { + case 'pshB': { + if (mEventRelated.isAdvance() && type == DOOR_TEMPLE_MAIN) { + int node; + node = mAnmChr.getModel().getNodeID("DoorF_L"); + if (node >= 0) { + mMtx_c nodeMtx; + mAnmChr.getModel().getNodeWorldMtx(node, nodeMtx); + mEmmiterL.startEffect(PARTICLE_RESOURCE_ID_MAPPING_935_, nodeMtx, nullptr, nullptr); + } + node = mAnmChr.getModel().getNodeID("DoorF_R"); + if (node >= 0) { + mMtx_c nodeMtx; + mAnmChr.getModel().getNodeWorldMtx(node, nodeMtx); + mEmmiterR.startEffect(PARTICLE_RESOURCE_ID_MAPPING_936_, nodeMtx, nullptr, nullptr); + } + } + } break; + case 'pshE': { + if (mEventRelated.isAdvance() && type == DOOR_TEMPLE_MAIN) { + int node; + node = mAnmChr.getModel().getNodeID("DoorF_L"); + if (node >= 0) { + mMtx_c nodeMtx; + mAnmChr.getModel().getNodeWorldMtx(node, nodeMtx); + mEmmiterL.startEffect(PARTICLE_RESOURCE_ID_MAPPING_933_, nodeMtx, nullptr, nullptr); + } + node = mAnmChr.getModel().getNodeID("DoorF_R"); + if (node >= 0) { + mMtx_c nodeMtx; + mAnmChr.getModel().getNodeWorldMtx(node, nodeMtx); + mEmmiterR.startEffect(PARTICLE_RESOURCE_ID_MAPPING_934_, nodeMtx, nullptr, nullptr); + } + } + } break; + } + + if (type != DOOR_TEMPLE_MAIN) { + bool b; + if (frame0 == frame1) { + b = frame0 == 16.f; + } else { + b = frame0 < 16.f && 16.f <= frame1; + } + if (b) { + startSound(SE_Door_W_OPEN); + } + } + + if (type != DOOR_TEMPLE_MAIN) { + bool b; + if (frame0 == frame1) { + b = frame0 == 60.f; + } else { + b = frame0 < 60.f && 60.f <= frame1; + } + if (b) { + startSound(SE_Door_W_CLOSE); + } + } + + if (mEventRelated.getCurrentEventCommand() == 'pshB' && type == DOOR_TEMPLE_MAIN) { + if (frame0 < 50.f && 50.f <= frame1) { + // TODO(Zeldex) - Why is this a check - This seems to indicate it was a getter for a pointer + if (&dRumble_c::sRumblePreset3) { + mRumbleIdx = + dRumble_c::start(dRumble_c::sRumblePreset3, dRumble_c::FLAG_SLOT0 | dRumble_c::FLAG_INITIALIZE); + } + } + if (frame0 <= 115.f && 115.f < frame1) { + dRumble_c::stop(mRumbleIdx); + } + } + return SUCCEEDED; +} + +int dAcOdoor_c::actorExecute() { + if (isTimeEffected()) { + fn_80067290(&mTimeBits, mRoomID, mPosition, 200.f); + } + switch (mEventCallbackType) { + case 0: { + bool b; + checkRoom(mRoomID, b); + if (b) { + setObjectProperty(OBJ_PROP_0x200); + return SUCCEEDED; + } + } break; + case 1: { + bool b; + checkRooms(b); + if (b) { + setObjectProperty(OBJ_PROP_0x200); + return SUCCEEDED; + } + } break; + } + unsetObjectProperty(OBJ_PROP_0x200); + s32 type = getType(); + + if (getLockParameter() == LOCK_KEY) { + if (mLock.get() == nullptr) { + if (isPlayerInteractable()) { + AttentionManager::GetInstance()->addTarget(*this, sOpenInteraction, 0, nullptr); + } + } else { + if (isPlayerInteractableLocked()) { + AttentionManager::GetInstance()->addTarget(*this, sOpenInteraction, 0, nullptr); + } + } + } else { + switch (mLockBehavior) { + case 0: { + if (isPlayerInteractable()) { + AttentionManager::GetInstance()->addTarget(*this, sOpenInteraction, 0, nullptr); + } + } break; + case 1: + case 4: + case 5: + case 6: { + if (isPlayerInteractable()) { + if (isLocked()) { + AttentionManager::GetInstance()->addTarget(*this, sLockedInteraction, 0, nullptr); + } else { + AttentionManager::GetInstance()->addTarget(*this, sOpenInteraction, 0, nullptr); + } + } + } break; + case 2: { + if (isPlayerInteractable()) { + AttentionManager::GetInstance()->addTarget(*this, sOpenInteraction, 0, nullptr); + } + } break; + case 3: { + if (!isLocked() && isPlayerInteractable()) { + AttentionManager::GetInstance()->addTarget(*this, sOpenInteraction, 0, nullptr); + } + } break; + } + } + + dAcObjBase_c *pObj = mObjRef.get(); + if (pObj != nullptr) { + mMtx_c m = pObj->mWorldMtx; + m += mMtx; + mWorldMtx = m; + mAnmChr.getModel().setLocalMtx(mWorldMtx); + mAnmChr.getModel().calc(false); + + if (type != DOOR_TEMPLE_MAIN) { + mMtx_c nodeMtx; + mAnmChr.getModel().getNodeWorldMtx(1, nodeMtx); + nodeMtx.transM(sDoorknobOffset0); + mMdl0.setLocalMtx(nodeMtx); + if (isTimeEffected()) { + mMdl1.setLocalMtx(nodeMtx); + } + } + } + + if (pObj != nullptr) { + mVec3_c min, max; + min.set(999999.f, 999999.f, 999999.f); + max.set(-999999.f, -999999.f, -999999.f); + + if (type == DOOR_TEMPLE_MAIN) { + mAnmChr.getModel().getBounds(&min, &max); + } else { + mVec3_c min_l, max_l; + mMtx_c local; + mMdl0.getBounds(&min_l, &max_l); + mMdl0.getLocalMtx(local); + + mMtx_c world = mWorldMtx; + world.inverse(); + + mVec3_c minPos = min_l; + local.multVec(minPos, minPos); + world.multVec(minPos, minPos); + + // clang-format off + min.set( + nw4r::ut::Min(minPos.x, min.x), + nw4r::ut::Min(minPos.y, min.y), + nw4r::ut::Min(minPos.z, min.z) + ); + max.set( + nw4r::ut::Max(minPos.x, max.x), + nw4r::ut::Max(minPos.y, max.y), + nw4r::ut::Max(minPos.z, max.z) + ); + // clang-format on + + mVec3_c maxPos = max_l; + local.multVec(maxPos, maxPos); + world.multVec(maxPos, maxPos); + // clang-format off + min.set( + nw4r::ut::Min(maxPos.x, min.x), + nw4r::ut::Min(maxPos.y, min.y), + nw4r::ut::Min(maxPos.z, min.z) + ); + max.set( + nw4r::ut::Max(maxPos.x, max.x), + nw4r::ut::Max(maxPos.y, max.y), + nw4r::ut::Max(maxPos.z, max.z) + ); + // clang-format on + + mVec3_c vecs[6] = { + mVec3_c(min_l.x, min_l.y, max_l.z), mVec3_c(min_l.x, max_l.y, min_l.z), + mVec3_c(min_l.x, max_l.y, max_l.z), mVec3_c(max_l.x, min_l.y, min_l.z), + mVec3_c(max_l.x, min_l.y, max_l.z), mVec3_c(max_l.x, max_l.y, min_l.z), + }; + + for (int i = 0, j = 0; i < (int)ARRAY_LENGTH(vecs); j++, i++) { + local.multVec(vecs[i], vecs[j]); + world.multVec(vecs[i], vecs[j]); + // clang-format off + min.set( + nw4r::ut::Min(vecs[j].x, min.x), + nw4r::ut::Min(vecs[j].y, min.y), + nw4r::ut::Min(vecs[j].z, min.z) + ); + max.set( + nw4r::ut::Max(vecs[j].x, max.x), + nw4r::ut::Max(vecs[j].y, max.y), + nw4r::ut::Max(vecs[j].z, max.z) + ); + // clang-format on + } + } + mBoundingBox.Set(min, max); + } + return SUCCEEDED; +} + +int dAcOdoor_c::draw() { + if (isTimeEffected()) { + if (!mTimeBits.field_0x00) { + drawModelType1(&mMdl1); + } + if (!mTimeBits.field_0x01) { + drawModelType1(&mMdl0); + } + } else { + if (getType() == DOOR_TEMPLE_MAIN) { + drawModelType1(&mAnmChr.getModel()); + } else { + drawModelType1(&mMdl0); + } + } + return SUCCEEDED; +} + +bool dAcOdoor_c::isLocked() { + if (getLockParameter() == LOCK_KEY) { + return mLock.isLinked(); + } + + switch (mLockBehavior) { + case LOCK_NEVER: { + return false; + } + case LOCK_NOT_SET: + case LOCK_TIMESHIFT: { + return mSceneflag < 0xFF ? !SceneflagManager::sInstance->checkBoolFlag(mRoomID, mSceneflag) : true; + } + case LOCK_NEVER1: { + return false; + } + case LOCK_SET: { + return mSceneflag < 0xFF ? SceneflagManager::sInstance->checkBoolFlag(mRoomID, mSceneflag) : true; + } + case LOCK_DAY: { + return dScGame_c::currentSpawnInfo.getTimeOfDay() == SpawnInfo::DAY; + } + case LOCK_NIGHT: { + return dScGame_c::currentSpawnInfo.getTimeOfDay() == SpawnInfo::NIGHT; + } + default: { + return true; + } + } +} + +bool dAcOdoor_c::canOpen() { + // NONMATCHING + // https://decomp.me/scratch/dHRfo + // Duplicate load of dStageMgr_c::sInstance for nullptr check and function call + // Happens in d_a_obj_door_boss as well + dStageMgr_c *pStageMgr = dStageMgr_c::GetInstance(); + if (pStageMgr != nullptr && pStageMgr->isAreaTypeDungeonOrBoss()) { + return getLockParameter() == LOCK_KEY && mLock.isLinked(); + } + return isLocked(); +} + +f32 dAcOdoor_c::fn_572_33E0() { + return -80.f; +} + +// HACK +inline u32 createBits(const u32 &a, const u32 &b) { + return a | b; +} + +void dAcOdoor_c::startPullEventWithoutCallback(void *zevData) { + Event event(DoorPull, zevData, 100, createBits(0x100001, 0x2), nullptr, nullptr); + mEventRelated.scheduleEvent(event, 0); +} + +void dAcOdoor_c::startPullEventWithCallback(void *zevData) { + Event event(DoorPull, zevData, 100, createBits(0x100001, 0x2), (void *)doorPullEventCallback, nullptr); + mEventRelated.scheduleEvent(event, 0); +} + +void dAcOdoor_c::startPushEventWithoutCallback(void *zevData) { + Event event(DoorPush, zevData, 100, createBits(0x100001, 0x2), nullptr, nullptr); + mEventRelated.scheduleEvent(event, 0); +} + +void dAcOdoor_c::startPushEventWithCallback(void *zevData) { + Event event(DoorPush, zevData, 100, createBits(0x100001, 0x2), (void *)doorPushEventCallback, nullptr); + mEventRelated.scheduleEvent(event, 0); +} + +void dAcOdoor_c::startPullEvent(void *zevData) { + switch (mEventCallbackType) { + case 0: startPullEventWithoutCallback(zevData); break; + case 1: startPullEventWithCallback(zevData); break; + } +} + +void dAcOdoor_c::startPushEvent(void *zevData) { + switch (mEventCallbackType) { + case 0: startPushEventWithoutCallback(zevData); break; + case 1: startPushEventWithCallback(zevData); break; + } +} + +void dAcOdoor_c::startOpenEvent(void *zevData) { + if (checkPullDoor()) { + startPullEvent(zevData); + } else { + // Cawlin and Strich's room has an awkward angle when pushing. + if (mbKobunDoor) { + Event event("KobunDoorPush", zevData, 100, 0x100001, nullptr, nullptr); + mEventRelated.scheduleEvent(event, 0); + } else { + startPushEvent(zevData); + } + } +} + +void dAcOdoor_c::doorPullEventCallback(void *pDoor) { + openCallbackCommon(pDoor); +} + +void dAcOdoor_c::doorPushEventCallback(void *pDoor) { + openCallbackCommon(pDoor); +} + +void dAcOdoor_c::startDoorPullLockedEvent(void *zevData) { + Event event(DoorPullLock, zevData, 100, 0x100001, (void *)pullLockedEventCallback, nullptr); + mEventRelated.scheduleEvent(event, 0); +} + +void dAcOdoor_c::startDoorPushLockedEvent(void *zevData) { + Event event(DoorPushLock, zevData, 100, 0x100001, (void *)pushLockedEventCallback, nullptr); + mEventRelated.scheduleEvent(event, 0); +} + +void dAcOdoor_c::startLockedEvent(void *zevData) { + if (checkPullDoor()) { + startDoorPullLockedEvent(zevData); + } else { + startDoorPushLockedEvent(zevData); + } +} + +void dAcOdoor_c::pullLockedEventCallback(void *vDoor) { + dAcOdoor_c *pDoor = static_cast(vDoor); + if (pDoor->hasFlowEntryPoint()) { + pDoor->playInteractionLocked(); + } + u16 flag = pDoor->getFailedToOpenFlag(); + if (flag < 0xFF) { + SceneflagManager::sInstance->setFlag(pDoor->mRoomID, flag); + } +} + +void dAcOdoor_c::pushLockedEventCallback(void *vDoor) { + dAcOdoor_c *pDoor = static_cast(vDoor); + if (pDoor->hasFlowEntryPoint()) { + pDoor->playInteractionLocked(); + } + u16 flag = pDoor->getFailedToOpenFlag(); + if (flag < 0xFF) { + SceneflagManager::sInstance->setFlag(pDoor->mRoomID, flag); + } +} + +void dAcOdoor_c::startUnlockEvent() { + Event event("ShutterUnlock", 100, 0x100001, (void *)unlockEventCallback, nullptr); + mEventRelated.scheduleEvent(event, 0); +} + +extern "C" void increaseSmallKeyCounter(int amt); + +void dAcOdoor_c::unlockEventCallback(void *vDoor) { + dAcOdoor_c *pDoor = static_cast(vDoor); + void *zevData = getOarcZev("DoorAnim"); + if (pDoor->checkPullDoor()) { + switch (pDoor->mEventCallbackType) { + case 0: { + Event event(DoorPull, zevData, 100, createBits(0x100001, 0x2), nullptr, nullptr); + EventManager::setEvent(pDoor, &event, nullptr); + } break; + case 1: { + Event event(DoorPull, zevData, 100, createBits(0x100001, 0x2), (void *)doorPullEventCallback, nullptr); + EventManager::setEvent(pDoor, &event, nullptr); + } break; + } + + } else { + switch (pDoor->mEventCallbackType) { + case 0: { + Event event(DoorPull, zevData, 100, createBits(0x100001, 0x2), nullptr, nullptr); + EventManager::setEvent(pDoor, &event, nullptr); + } break; + case 1: { + Event event(DoorPull, zevData, 100, createBits(0x100001, 0x2), (void *)doorPullEventCallback, nullptr); + EventManager::setEvent(pDoor, &event, nullptr); + } break; + } + } + + if (pDoor->mSceneflag < 0xFF) { + SceneflagManager::sInstance->setFlag(pDoor->mRoomID, pDoor->mSceneflag); + } + + increaseSmallKeyCounter(-1); +} + +void dAcOdoor_c::openCallbackCommon(void *vDoor) { + if (vDoor == nullptr) { + return; + } + dAcOdoor_c *pDoor = static_cast(vDoor); + + bool search = true; + dAcOFence_c *pFence = static_cast(fManager_c::searchBaseByProfName(fProfile::OBJ_FENCE, nullptr)); + while (search && pFence != nullptr) { + if (mAng::abs(dAcPy_c::GetLink()->mRotation.y - pFence->mRotation.y) < 0x4000) { + const mVec3_c &posFence = pFence->mPosition; + const mVec3_c &position = pDoor->mPosition; + if (posFence.squareDistanceToXZ(position) < 22500.f && nw4r::math::FAbs(posFence.y - position.y) < 500.f) { + pFence->setObjectProperty(OBJ_PROP_0x200); + pFence->fn_550_1250(); + pFence->fn_550_12B0(); + search = false; + continue; + } + } + pFence = static_cast(fManager_c::searchBaseByProfName(fProfile::OBJ_FENCE, pFence)); + } +} + +void dAcOdoor_c::registerInEvent() { + if (isInTimeDoorEvent()) { + setTimeDoorEventActive(); + } +} + +void dAcOdoor_c::unkVirtFunc_0x6C() { + setTimeDoorEventInactive(); +} + +void dAcOdoor_c::doInteraction(s32 interaction) { + if (getType() == DOOR_TEMPLE_MAIN) { + void *zevData = getOarcZev("DoorF"); + Event event("FTypeDoorOut", zevData, 100, createBits(0x100001, 0x2), nullptr, nullptr); + mEventRelated.scheduleEvent(event, 0); + return; + } + + void *zevData = getOarcZev("DoorAnim"); + + switch (interaction) { + case OPEN: { + if (getLockParameter() == LOCK_KEY) { + if (!mLock.isLinked()) { + startOpenEvent(zevData); + } else { + if (dAcItem_c::getSmallKeyCount() != 0) { + if (isConnectedToOtherDoor()) { + if (isPlayerInteractable()) { + startUnlockEvent(); + } else { + dAcOdoor_c *pDoor = getConnectedDoorRef().get(); + pDoor->mLock.link(mLock.get()); + pDoor->startUnlockEvent(); + } + } else { + startOpenEvent(zevData); + } + } else { + Event event(getDoorInteractionName(), 100, 0x100001, nullptr, nullptr); + mEventRelated.scheduleEvent(event, 0); + } + } + } else { + startOpenEvent(zevData); + if (mLockBehavior == LOCK_NEVER1 && mSceneflag < 0xFF) { + SceneflagManager::sInstance->setFlag(mRoomID, mSceneflag); + } + } + } break; + case EXAMINE_TALK: { + startLockedEvent(zevData); + } break; + } +} + +s32 dAcOdoor_c::getLockParameter() { + return getFromParams(6, 0x1); +} + +s32 dAcOdoor_c::getLockBehavior() { + return (mRotation.x >> 0) & 0xFF; +} + +u8 dAcOdoor_c::getSceneflag() { + return (mRotation.x >> 8) & 0xFF; +} + +u8 dAcOdoor_c::getDoorCallbackType() { + return (mRotation.z >> 0) & 0xF; +} + +u8 dAcOdoor_c::getFrontRoomParam() { + return (mRotation.z >> 4) & 0x3F; +} + +u8 dAcOdoor_c::getBackRoomParam() { + return (mRotation.z >> 10) & 0x3F; +} + +u16 dAcOdoor_c::getFailedToOpenFlag() { + return getParams2Lower() & 0xFF; +} + +f32 dAcOdoor_c::getInteractionMinX() { + return -80.f; +} + +f32 dAcOdoor_c::getInteractionMaxX() { + return 80.f; +} + +f32 dAcOdoor_c::getInteractionMinZ() { + return -100.f; +} + +f32 dAcOdoor_c::getInteractionMaxZ() { + return 100.f; +} + +f32 dAcOdoor_c::getInteractionLockMinX() { + return -160.f; +} + +f32 dAcOdoor_c::getInteractionLockMaxX() { + return 160.f; +} + +f32 dAcOdoor_c::getInteractionLockMinZ() { + return -100.f; +} + +f32 dAcOdoor_c::getInteractionLockMaxZ() { + return 100.f; +} + +void dAcOdoor_c::setRoomId(s8 roomId) { + mRoomID = roomId; +} + +void dAcOdoor_c::setFlag(u32 flags) { + mFlags = flags; +} + +void dAcOdoor_c::setEventCallbackType(u8 in) { + mEventCallbackType = in; +} + +void dAcOdoor_c::setFrontRoom(s8 in) { + mFrontRoomId = in; +} + +void dAcOdoor_c::setBackRoom(s8 in) { + mBackRoomId = in; +} + +void dAcOdoor_c::setDoubleDoor() { + mbDoubleDoor = true; +} + +void dAcOdoor_c::setNotDoubleDoor() { + mbDoubleDoor = false; +} + +void dAcOdoor_c::setSingleDoor() { + mbSingleDoor = true; +} + +void dAcOdoor_c::setNotSingleDoor() { + mbSingleDoor = false; +} + +void dAcOdoor_c::setInSandshipBoss() { + mbInSandshipBoss = true; +} + +bool dAcOdoor_c::isTimeDoorEventActive() const { + return mFlags & 1; +} + +void dAcOdoor_c::setTimeDoorEventActive() { + setFlag(mFlags | 1); +} + +void dAcOdoor_c::setTimeDoorEventInactive() { + setFlag(mFlags & ~1); +} + +void dAcOdoor_c::setTimeEffected() { + setFlag(mFlags | 2); +} + +void dAcOdoor_c::setTimeStatic() { + setFlag(mFlags & ~2); +} + +bool dAcOdoor_c::checkFrontRoom(bool &b) const { + return checkRoom(mFrontRoomId, b); +} + +bool dAcOdoor_c::checkBackRoom(bool &b) const { + return checkRoom(mBackRoomId, b); +} + +bool dAcOdoor_c::checkRooms(bool &b) const { + bool b0, b1; + if (!checkFrontRoom(b0)) { + return false; + } + if (!checkBackRoom(b1)) { + return false; + } + b = b0 && b1; + return true; +} + +void dAcOdoor_c::triggerExit() { + if (isLeavingSealedTempleSideDoorPostSkyKeep()) { + dScGame_c::GetInstance()->triggerExit(mRoomID, 11, 2, 2); + } else { + dScGame_c::GetInstance()->triggerExit(mRoomID, getFromParams(8, 0xFF), 2, 2); + } +} + +bool dAcOdoor_c::isLeavingSealedTempleSideDoorPostSkyKeep() const { + return s32(mParams & 0x3F) == DOOR_TEMPLE_SIDE && mBackRoomId == 1 && + StoryflagManager::sInstance->getFlag(STORYFLAG_342) && dScGame_c::isCurrentStage(sStageF402); +} + +void dAcOdoor_c::transitionPushRoomFlags() const { + if (dStage_c::GetInstance() == nullptr) { + return; + } + dStage_c::GetInstance()->updateRoomFlags(getField_0x5B4(), getField_0x5B5()); +} + +void dAcOdoor_c::transitionPullRoomFlags() const { + if (dStage_c::GetInstance() == nullptr) { + return; + } + dStage_c::GetInstance()->updateRoomFlags(getField_0x5B5(), getField_0x5B4()); +} + +bool dAcOdoor_c::isPositionInFrontOfDoor(const mVec3_c &point) const { + s32 diff = mRotation.y - (point - mPosition).atan2sX_Z(); + return mAng::abs(diff) <= 0x4000; +} + +bool dAcOdoor_c::checkPullDoor() const { + return isPositionInFrontOfDoor(dAcPy_c::GetLink()->mPosition); +} + +bool dAcOdoor_c::hasFlowEntryPoint() { + return getFromParams(16, 0xFFFF); +} + +bool dAcOdoor_c::isTimeEffected() const { + return mFlags & 2; +} + +void dAcOdoor_c::setDoorKnobPosition() { + mVec3_c pos; + if (getType() == DOOR_TEMPLE_MAIN) { + pos.set(mPosition); + pos.y += 150.f; + } else { + mMtx_c m; + mAnmChr.getModel().getNodeWorldMtx(1, m); + m.transM(sDoorknobOffset0); + m.multVec(sDoorknobOffset1, pos); + } + mPositionCopy2.set(pos); + mPositionCopy3.set(pos); +} + +bool dAcOdoor_c::isPlayerInteractable() const { + mVec3_c v = dAcPy_c::GetLink()->mPosition; + v -= mPosition; + v.rotY(-mRotation.y); + + if (v.x < getInteractionMinX()) { + return false; + } + if (getInteractionMaxX() < v.x) { + return false; + } + if (v.z < getInteractionMinZ()) { + return false; + } + if (getInteractionMaxZ() < v.z) { + return false; + } + return true; +} + +bool dAcOdoor_c::isPlayerInteractableLocked() const { + mVec3_c v = dAcPy_c::GetLink()->mPosition; + v -= mPosition; + v.rotY(-mRotation.y); + v.x += 80.f; + + if (v.x < getInteractionLockMinX()) { + return false; + } + if (getInteractionLockMaxX() < v.x) { + return false; + } + if (v.z < getInteractionLockMinZ()) { + return false; + } + if (getInteractionLockMaxZ() < v.z) { + return false; + } + return true; +} + +void dAcOdoor_c::playInteractionLocked() { + Event event(getDoorInteractionName(), 100, 0x100001, nullptr, nullptr); + EventManager::setEvent(this, &event, nullptr); +} diff --git a/src/REL/d/a/obj/d_a_obj_door_boss.cpp b/src/REL/d/a/obj/d_a_obj_door_boss.cpp index 3331f4884..f218cc762 100644 --- a/src/REL/d/a/obj/d_a_obj_door_boss.cpp +++ b/src/REL/d/a/obj/d_a_obj_door_boss.cpp @@ -18,6 +18,10 @@ STATE_DEFINE(dAcOdoorBoss_c, Close); STATE_DEFINE(dAcOdoorBoss_c, Idle); STATE_DEFINE(dAcOdoorBoss_c, BeforeTimeShift); +bool dAcOdoorBoss_c::canOpen() { + // Not implemented - Used to emit dtor + return true; +} void dAcOdoorBoss_c::initializeState_UnlockWait() {} void dAcOdoorBoss_c::executeState_UnlockWait() {} void dAcOdoorBoss_c::finalizeState_UnlockWait() {} diff --git a/src/REL/d/a/obj/d_a_obj_shutter.cpp b/src/REL/d/a/obj/d_a_obj_shutter.cpp index 152806539..ca344cf26 100644 --- a/src/REL/d/a/obj/d_a_obj_shutter.cpp +++ b/src/REL/d/a/obj/d_a_obj_shutter.cpp @@ -6,6 +6,11 @@ STATE_DEFINE(dAcOShutter_c, Wait); STATE_DEFINE(dAcOShutter_c, Open); STATE_DEFINE(dAcOShutter_c, Close); +bool dAcOShutter_c::canOpen() { + // Not implemented - Used to emit dtor + return true; +} + void dAcOShutter_c::initializeState_Wait() {} void dAcOShutter_c::executeState_Wait() {} void dAcOShutter_c::finalizeState_Wait() {} diff --git a/src/REL/d/a/obj/d_a_obj_shutter_change_scene.cpp b/src/REL/d/a/obj/d_a_obj_shutter_change_scene.cpp index 998f65808..6dfd18770 100644 --- a/src/REL/d/a/obj/d_a_obj_shutter_change_scene.cpp +++ b/src/REL/d/a/obj/d_a_obj_shutter_change_scene.cpp @@ -1,9 +1,16 @@ #include "d/a/obj/d_a_obj_shutter_change_scene.h" +#include "f/f_base.h" + SPECIAL_ACTOR_PROFILE( OBJ_SHUTTER_CHANGE_SCENE, dAcOShutterChangeScene_c, fProfile::OBJ_SHUTTER_CHANGE_SCENE, 0x18A, 0, 6 ); +bool dAcOShutterChangeScene_c::canOpen() { + // Not implemented - Used to emit dtor + return true; +} + STATE_DEFINE(dAcOShutterChangeScene_c, WaitOpenShutter); STATE_DEFINE(dAcOShutterChangeScene_c, WaitOpenShutterForEvent); STATE_DEFINE(dAcOShutterChangeScene_c, OpenShutter); diff --git a/src/REL/d/a/obj/d_a_obj_tr_shutter_cs.cpp b/src/REL/d/a/obj/d_a_obj_tr_shutter_cs.cpp index 9cfaeb746..d7a0e3c62 100644 --- a/src/REL/d/a/obj/d_a_obj_tr_shutter_cs.cpp +++ b/src/REL/d/a/obj/d_a_obj_tr_shutter_cs.cpp @@ -5,6 +5,10 @@ SPECIAL_ACTOR_PROFILE(OBJ_TR_SHUTTER_CS, dAcOTrlyShtrChgScn_c, fProfile::OBJ_TR_ STATE_DEFINE(dAcOTrlyShtrChgScn_c, Wait); STATE_DEFINE(dAcOTrlyShtrChgScn_c, OpenEvent); +bool dAcOTrlyShtrChgScn_c::canOpen() { + // Not implemented - Used to emit dtor + return true; +} void dAcOTrlyShtrChgScn_c::initializeState_Wait() {} void dAcOTrlyShtrChgScn_c::executeState_Wait() {} void dAcOTrlyShtrChgScn_c::finalizeState_Wait() {} diff --git a/src/REL/d/a/obj/d_a_obj_trolley_shutter.cpp b/src/REL/d/a/obj/d_a_obj_trolley_shutter.cpp index d561937e2..fbc33114e 100644 --- a/src/REL/d/a/obj/d_a_obj_trolley_shutter.cpp +++ b/src/REL/d/a/obj/d_a_obj_trolley_shutter.cpp @@ -5,6 +5,10 @@ SPECIAL_ACTOR_PROFILE(OBJ_TROLLEY_SHUTTER, dAcOTrolleyShutter_c, fProfile::OBJ_T STATE_DEFINE(dAcOTrolleyShutter_c, Wait); STATE_DEFINE(dAcOTrolleyShutter_c, OpenEvent); +bool dAcOTrolleyShutter_c::canOpen() { + // Not implemented - Used to emit dtor + return true; +} void dAcOTrolleyShutter_c::initializeState_Wait() {} void dAcOTrolleyShutter_c::executeState_Wait() {} void dAcOTrolleyShutter_c::finalizeState_Wait() {}