diff --git a/config/GM8E01_00/symbols.txt b/config/GM8E01_00/symbols.txt index 87dd2dfb..2eed28ae 100644 --- a/config/GM8E01_00/symbols.txt +++ b/config/GM8E01_00/symbols.txt @@ -139,7 +139,7 @@ SetupInterpolation__14CCameraManagerFRC12CTransform4f9TUniqueId9CVector3ffffbR13 SetPlayerCamera__14CCameraManagerFR13CStateManager9TUniqueId = .text:0x8000A848; // type:function size:0x84 scope:global ShouldBypassInterpolationCamera__14CCameraManagerCFv = .text:0x8000A8CC; // type:function size:0x8 scope:global IsInterpolationCameraActive__14CCameraManagerCFv = .text:0x8000A8D4; // type:function size:0x10 scope:global -IsInFirstPersonCamera__14CCameraManagerCFv = .text:0x8000A8E4; // type:function size:0x1C scope:global +IsInFPCamera__14CCameraManagerCFv = .text:0x8000A8E4; // type:function size:0x1C scope:global IsInCinematicCamera__14CCameraManagerCFv = .text:0x8000A900; // type:function size:0x14 scope:global GetGlobalCameraTranslation__14CCameraManagerCFRC13CStateManager = .text:0x8000A914; // type:function size:0x54 scope:global GetCurrentCameraTransform__14CCameraManagerCFRC13CStateManager = .text:0x8000A968; // type:function size:0x68 scope:global @@ -288,25 +288,25 @@ IsQualified__11CObjectListFRC7CEntity = .text:0x80010030; // type:function size: __ct__11CObjectListF15EGameObjectList = .text:0x80010038; // type:function size:0xF4 scope:global __ct__Q211CObjectList16SObjectListEntryFv = .text:0x8001012C; // type:function size:0x18 scope:weak __dt__7CPlayerFv = .text:0x80010144; // type:function size:0x730 scope:global -fn_80010874 = .text:0x80010874; // type:function size:0x58 +__dt__Q24rstl43single_ptrFv = .text:0x80010874; // type:function size:0x58 __dt__Q27CPlayer19CPlayerStuckTrackerFv = .text:0x800108CC; // type:function size:0x1CC scope:global IsTransparent__7CPlayerCFv = .text:0x80010A98; // type:function size:0x18 scope:global IsEnergyLow__7CPlayerCFRC13CStateManager = .text:0x80010AB0; // type:function size:0x7C scope:global FinishNewScan__7CPlayerFR13CStateManager = .text:0x80010B2C; // type:function size:0x12C scope:global GetAttachedActorStruggle__7CPlayerCFv = .text:0x80010C58; // type:function size:0x8 scope:global StartSamusVoiceSfx__7CPlayerFUssi = .text:0x80010C60; // type:function size:0xD0 scope:global -PostUpdate__7CPlayerFfR13CStateManager = .text:0x80010D30; // type:function size:0x1D4 scope:global -__ct__16CPlayerCameraBobFRC16CPlayerCameraBob = .text:0x80010F04; // type:function size:0x270 scope:global +DoPostCameraStuff__7CPlayerFfR13CStateManager = .text:0x80010D30; // type:function size:0x1D4 scope:global +__as__16CPlayerCameraBobFRC16CPlayerCameraBob = .text:0x80010F04; // type:function size:0x270 scope:global SetPlayerHitWallDuringMove__7CPlayerFv = .text:0x80011174; // type:function size:0x18 scope:global DoSfxEffects__7CPlayerF10CSfxHandle = .text:0x8001118C; // type:function size:0x48 scope:global UpdatePhazonDamage__7CPlayerFfR13CStateManager = .text:0x800111D4; // type:function size:0x578 scope:global -__dt__17CCollidableSphere = .text:0x8001174C; // type:function size:0x5C scope:global +__dt__17CCollidableSphereFv = .text:0x8001174C; // type:function size:0x5C scope:global __dt__19CCollisionPrimitiveFv = .text:0x800117A8; // type:function size:0x48 scope:global UpdatePhazonCameraShake__7CPlayerFfR13CStateManager = .text:0x800117F0; // type:function size:0x154 scope:global -DecrementPhazon__7CPlayerFv = .text:0x80011944; // type:function size:0x18 scope:global -IncrementPhazon__7CPlayerFv = .text:0x8001195C; // type:function size:0x24 scope:global -DoPreThink__7CPlayerFfRC13CStateManager = .text:0x80011980; // type:function size:0x84 scope:global -DoThink__7CPlayerFfRC13CStateManager = .text:0x80011A04; // type:function size:0x84 scope:global +DecrementEnvironmentDamage__7CPlayerFv = .text:0x80011944; // type:function size:0x18 scope:global +IncrementEnvironmentDamage__7CPlayerFv = .text:0x8001195C; // type:function size:0x24 scope:global +DoPreThink__7CPlayerFfR13CStateManager = .text:0x80011980; // type:function size:0x84 scope:global +DoThink__7CPlayerFfR13CStateManager = .text:0x80011A04; // type:function size:0x84 scope:global ResetControlDirectionInterpolation__7CPlayerFv = .text:0x80011A88; // type:function size:0x1C scope:global SetControlDirectionInterpolation__7CPlayerFf = .text:0x80011AA4; // type:function size:0x20 scope:global IsPlayerDeadEnough__7CPlayerCFv = .text:0x80011AC4; // type:function size:0x68 scope:global @@ -336,7 +336,7 @@ SetHudDisable__7CPlayerFfff = .text:0x8001306C; // type:function size:0x3C scope GetTouchBounds__7CPlayerCFv = .text:0x800130A8; // type:function size:0x160 scope:global Touch__7CPlayerFR6CActorR13CStateManager = .text:0x80013208; // type:function size:0x30 scope:global UpdateScanningState__7CPlayerFRC11CFinalInputR13CStateManagerf = .text:0x80013238; // type:function size:0x2CC scope:global -ValidateScanning__7CPlayerFRC11CFinalInputR13CStateManager = .text:0x80013504; // type:function size:0x11C scope:global +ValidateScanning__7CPlayerCFRC11CFinalInputR13CStateManager = .text:0x80013504; // type:function size:0x11C scope:global SetScanningState__7CPlayerFQ27CPlayer16EPlayerScanStateR13CStateManager = .text:0x80013620; // type:function size:0x1F0 scope:global GetExplorationMode__7CPlayerCFv = .text:0x80013810; // type:function size:0x38 scope:global GetCombatMode__7CPlayerCFv = .text:0x80013848; // type:function size:0x38 scope:global @@ -348,7 +348,7 @@ RenderReflectedPlayer__7CPlayerFR13CStateManager = .text:0x80014174; // type:fun PreRender__7CPlayerFR13CStateManagerRC14CFrustumPlanes = .text:0x800142C0; // type:function size:0x120 scope:global CalculateRenderBounds__7CPlayerFv = .text:0x800143E0; // type:function size:0xC0 scope:global AddToRenderer__7CPlayerCFRC14CFrustumPlanesRC13CStateManager = .text:0x800144A0; // type:function size:0xAC scope:global -UpdateGunAlpha__7CPlayerFRC13CStateManager = .text:0x8001454C; // type:function size:0xCC scope:global +UpdateGunAlpha__7CPlayerFv = .text:0x8001454C; // type:function size:0xCC scope:global ComputeFreeLook__7CPlayerFRC11CFinalInput = .text:0x80014618; // type:function size:0x208 scope:global UpdateFreeLook__7CPlayerFf = .text:0x80014820; // type:function size:0x184 scope:global DetachActorFromPlayer__7CPlayerFv = .text:0x800149A4; // type:function size:0x2C scope:global @@ -7667,7 +7667,7 @@ BuildPatternedExplodeShakeData__16CCameraShakeDataFRC9CVector3ffff = .text:0x801 BuildLandingCameraShake__16CCameraShakeDataFff = .text:0x8015D6C4; // type:function size:0x16C scope:global __ct__16CCameraShakeDataFff = .text:0x8015D830; // type:function size:0x108 scope:global BuildPatternedExplodeShakeData__16CCameraShakeDataFff = .text:0x8015D938; // type:function size:0x108 scope:global -BuildPhazonCameraShakeData__16CCameraShakeDataFff = .text:0x8015DA40; // type:function size:0x174 scope:global +SoftBothAxesShake__16CCameraShakeDataFff = .text:0x8015DA40; // type:function size:0x174 scope:global BuildProjectileCameraShake__16CCameraShakeDataFff = .text:0x8015DBB4; // type:function size:0x100 scope:global __sinit_CCameraShakeData_cpp = .text:0x8015DCB4; // type:function size:0x1D4 scope:local Accept__22CScriptPickupGeneratorFR8IVisitor = .text:0x8015DE88; // type:function size:0x38 scope:global @@ -18006,7 +18006,7 @@ gPressInputs__13ControlMapper = .data:0x803D93F8; // type:object size:0x114 scop @336 = .data:0x803D9600; // type:object size:0x5C scope:local lbl_803D9660 = .data:0x803D9660; // type:object size:0x78 __vt__11CObjectList = .data:0x803D96D8; // type:object size:0xC scope:global -lbl_803D96E8 = .data:0x803D96E8; // type:object size:0x88 +__vt__7CPlayer = .data:0x803D96E8; // type:object size:0x88 jumptable_803D9770 = .data:0x803D9770; // type:object size:0x1C scope:local jumptable_803D978C = .data:0x803D978C; // type:object size:0x58 scope:local __vt__19CCollisionPrimitive = .data:0x803D97E4; // type:object size:0x2C scope:global @@ -19126,8 +19126,8 @@ testRayResult = .bss:0x80457920; // type:object size:0x30 testBoxResult = .bss:0x80457950; // type:object size:0x60 testBox = .bss:0x804579B0; // type:object size:0x18 data:float skVisorToItemMapping = .bss:0x804579C8; // type:object size:0x20 data:4byte -lbl_804579E8 = .bss:0x804579E8; // type:object size:0x10 data:float -lbl_804579F8 = .bss:0x804579F8; // type:object size:0x18 data:4byte +skDown$1100 = .bss:0x804579E8; // type:object size:0xC data:float +matFilter$1103 = .bss:0x804579F8; // type:object size:0x18 data:4byte sAllocSpace$2944 = .bss:0x80457A10; // type:object size:0x838 sAllocSpace$2964 = .bss:0x80458248; // type:object size:0x108 sAllocSpace$2980 = .bss:0x80458350; // type:object size:0x1E58 @@ -21498,18 +21498,18 @@ lbl_805A8C70 = .sbss:0x805A8C70; // type:object size:0x4 data:4byte lbl_805A8C74 = .sbss:0x805A8C74; // type:object size:0x1 data:byte gUseSurfaceHack = .sbss:0x805A8C78; // type:object size:0x1 data:byte gSR_Hack = .sbss:0x805A8C7C; // type:object size:0x4 data:4byte -lbl_805A8C80 = .sbss:0x805A8C80; // type:object size:0x1 data:byte -lbl_805A8C81 = .sbss:0x805A8C81; // type:object size:0x1 data:byte -lbl_805A8C84 = .sbss:0x805A8C84; // type:object size:0x4 data:float -lbl_805A8C88 = .sbss:0x805A8C88; // type:object size:0x1 data:byte -lbl_805A8C8C = .sbss:0x805A8C8C; // type:object size:0x4 data:4byte -lbl_805A8C90 = .sbss:0x805A8C90; // type:object size:0x1 data:byte -lbl_805A8C94 = .sbss:0x805A8C94; // type:object size:0x4 data:4byte -lbl_805A8C98 = .sbss:0x805A8C98; // type:object size:0x1 data:byte -lbl_805A8C9C = .sbss:0x805A8C9C; // type:object size:0x4 data:4byte -lbl_805A8CA0 = .sbss:0x805A8CA0; // type:object size:0x1 data:byte -lbl_805A8CA4 = .sbss:0x805A8CA4; // type:object size:0x4 data:4byte -lbl_805A8CA8 = .sbss:0x805A8CA8; // type:object size:0x8 data:byte +init$1101 = .sbss:0x805A8C80; // type:object size:0x1 data:byte +init$1105 = .sbss:0x805A8C81; // type:object size:0x1 data:byte +earHeight$1154 = .sbss:0x805A8C84; // type:object size:0x4 data:float +init$1155 = .sbss:0x805A8C88; // type:object size:0x1 data:byte +sReferenceCount$9741 = .sbss:0x805A8C8C; // type:object size:0x4 data:4byte +init$9742 = .sbss:0x805A8C90; // type:object size:0x1 data:byte +sReferenceCount$9761 = .sbss:0x805A8C94; // type:object size:0x4 data:4byte +init$9762 = .sbss:0x805A8C98; // type:object size:0x1 data:byte +sReferenceCount$9777 = .sbss:0x805A8C9C; // type:object size:0x4 data:4byte +init$9778 = .sbss:0x805A8CA0; // type:object size:0x1 data:byte +sReferenceCount$9788 = .sbss:0x805A8CA4; // type:object size:0x4 data:4byte +init$9789 = .sbss:0x805A8CA8; // type:object size:0x1 data:byte lbl_805A8CB0 = .sbss:0x805A8CB0; // type:object size:0x8 data:4byte lbl_805A8CB8 = .sbss:0x805A8CB8; // type:object size:0x8 data:4byte lbl_805A8CC0 = .sbss:0x805A8CC0; // type:object size:0x4 data:4byte diff --git a/config/GM8E01_01/symbols.txt b/config/GM8E01_01/symbols.txt index fc948a6f..fe020edf 100644 --- a/config/GM8E01_01/symbols.txt +++ b/config/GM8E01_01/symbols.txt @@ -139,7 +139,7 @@ SetupInterpolation__14CCameraManagerFRC12CTransform4f9TUniqueId9CVector3ffffbR13 SetPlayerCamera__14CCameraManagerFR13CStateManager9TUniqueId = .text:0x8000A8C4; // type:function size:0x84 scope:global ShouldBypassInterpolationCamera__14CCameraManagerCFv = .text:0x8000A948; // type:function size:0x8 scope:global IsInterpolationCameraActive__14CCameraManagerCFv = .text:0x8000A950; // type:function size:0x10 scope:global -IsInFirstPersonCamera__14CCameraManagerCFv = .text:0x8000A960; // type:function size:0x1C scope:global +IsInFPCamera__14CCameraManagerCFv = .text:0x8000A960; // type:function size:0x1C scope:global IsInCinematicCamera__14CCameraManagerCFv = .text:0x8000A97C; // type:function size:0x14 scope:global GetGlobalCameraTranslation__14CCameraManagerCFRC13CStateManager = .text:0x8000A990; // type:function size:0x54 scope:global GetCurrentCameraTransform__14CCameraManagerCFRC13CStateManager = .text:0x8000A9E4; // type:function size:0x68 scope:global @@ -288,25 +288,25 @@ IsQualified__11CObjectListFRC7CEntity = .text:0x800100AC; // type:function size: __ct__11CObjectListF15EGameObjectList = .text:0x800100B4; // type:function size:0xF4 scope:global __ct__Q211CObjectList16SObjectListEntryFv = .text:0x800101A8; // type:function size:0x18 scope:weak __dt__7CPlayerFv = .text:0x800101C0; // type:function size:0x730 scope:global -fn_80010874 = .text:0x800108F0; // type:function size:0x58 scope:global +__dt__Q24rstl43single_ptrFv = .text:0x800108F0; // type:function size:0x58 scope:global __dt__Q27CPlayer19CPlayerStuckTrackerFv = .text:0x80010948; // type:function size:0x1CC scope:global IsTransparent__7CPlayerCFv = .text:0x80010B14; // type:function size:0x18 scope:global IsEnergyLow__7CPlayerCFRC13CStateManager = .text:0x80010B2C; // type:function size:0x7C scope:global FinishNewScan__7CPlayerFR13CStateManager = .text:0x80010BA8; // type:function size:0x12C scope:global GetAttachedActorStruggle__7CPlayerCFv = .text:0x80010CD4; // type:function size:0x8 scope:global StartSamusVoiceSfx__7CPlayerFUssi = .text:0x80010CDC; // type:function size:0xD0 scope:global -PostUpdate__7CPlayerFfR13CStateManager = .text:0x80010DAC; // type:function size:0x1D4 scope:global -__ct__16CPlayerCameraBobFRC16CPlayerCameraBob = .text:0x80010F80; // type:function size:0x270 scope:global +DoPostCameraStuff__7CPlayerFfR13CStateManager = .text:0x80010DAC; // type:function size:0x1D4 scope:global +__as__16CPlayerCameraBobFRC16CPlayerCameraBob = .text:0x80010F80; // type:function size:0x270 scope:global SetPlayerHitWallDuringMove__7CPlayerFv = .text:0x800111F0; // type:function size:0x18 scope:global DoSfxEffects__7CPlayerF10CSfxHandle = .text:0x80011208; // type:function size:0x48 scope:global UpdatePhazonDamage__7CPlayerFfR13CStateManager = .text:0x80011250; // type:function size:0x578 scope:global -__dt__17CCollidableSphere = .text:0x800117C8; // type:function size:0x5C scope:global +__dt__17CCollidableSphereFv = .text:0x800117C8; // type:function size:0x5C scope:global __dt__19CCollisionPrimitiveFv = .text:0x80011824; // type:function size:0x48 scope:global UpdatePhazonCameraShake__7CPlayerFfR13CStateManager = .text:0x8001186C; // type:function size:0x154 scope:global -DecrementPhazon__7CPlayerFv = .text:0x800119C0; // type:function size:0x18 scope:global -IncrementPhazon__7CPlayerFv = .text:0x800119D8; // type:function size:0x24 scope:global -DoPreThink__7CPlayerFfRC13CStateManager = .text:0x800119FC; // type:function size:0x84 scope:global -DoThink__7CPlayerFfRC13CStateManager = .text:0x80011A80; // type:function size:0x84 scope:global +DecrementEnvironmentDamage__7CPlayerFv = .text:0x800119C0; // type:function size:0x18 scope:global +IncrementEnvironmentDamage__7CPlayerFv = .text:0x800119D8; // type:function size:0x24 scope:global +DoPreThink__7CPlayerFfR13CStateManager = .text:0x800119FC; // type:function size:0x84 scope:global +DoThink__7CPlayerFfR13CStateManager = .text:0x80011A80; // type:function size:0x84 scope:global ResetControlDirectionInterpolation__7CPlayerFv = .text:0x80011B04; // type:function size:0x1C scope:global SetControlDirectionInterpolation__7CPlayerFf = .text:0x80011B20; // type:function size:0x20 scope:global IsPlayerDeadEnough__7CPlayerCFv = .text:0x80011B40; // type:function size:0x68 scope:global @@ -336,7 +336,7 @@ SetHudDisable__7CPlayerFfff = .text:0x800130E8; // type:function size:0x3C scope GetTouchBounds__7CPlayerCFv = .text:0x80013124; // type:function size:0x160 scope:global Touch__7CPlayerFR6CActorR13CStateManager = .text:0x80013284; // type:function size:0x30 scope:global UpdateScanningState__7CPlayerFRC11CFinalInputR13CStateManagerf = .text:0x800132B4; // type:function size:0x2CC scope:global -ValidateScanning__7CPlayerFRC11CFinalInputR13CStateManager = .text:0x80013580; // type:function size:0x11C scope:global +ValidateScanning__7CPlayerCFRC11CFinalInputR13CStateManager = .text:0x80013580; // type:function size:0x11C scope:global SetScanningState__7CPlayerFQ27CPlayer16EPlayerScanStateR13CStateManager = .text:0x8001369C; // type:function size:0x1F0 scope:global GetExplorationMode__7CPlayerCFv = .text:0x8001388C; // type:function size:0x38 scope:global GetCombatMode__7CPlayerCFv = .text:0x800138C4; // type:function size:0x38 scope:global @@ -348,7 +348,7 @@ RenderReflectedPlayer__7CPlayerFR13CStateManager = .text:0x800141F0; // type:fun PreRender__7CPlayerFR13CStateManagerRC14CFrustumPlanes = .text:0x8001433C; // type:function size:0x120 scope:global CalculateRenderBounds__7CPlayerFv = .text:0x8001445C; // type:function size:0xC0 scope:global AddToRenderer__7CPlayerCFRC14CFrustumPlanesRC13CStateManager = .text:0x8001451C; // type:function size:0xAC scope:global -UpdateGunAlpha__7CPlayerFRC13CStateManager = .text:0x800145C8; // type:function size:0xCC scope:global +UpdateGunAlpha__7CPlayerFv = .text:0x800145C8; // type:function size:0xCC scope:global ComputeFreeLook__7CPlayerFRC11CFinalInput = .text:0x80014694; // type:function size:0x208 scope:global UpdateFreeLook__7CPlayerFf = .text:0x8001489C; // type:function size:0x184 scope:global DetachActorFromPlayer__7CPlayerFv = .text:0x80014A20; // type:function size:0x2C scope:global @@ -7670,7 +7670,7 @@ BuildPatternedExplodeShakeData__16CCameraShakeDataFRC9CVector3ffff = .text:0x801 BuildLandingCameraShake__16CCameraShakeDataFff = .text:0x8015D740; // type:function size:0x16C scope:global __ct__16CCameraShakeDataFff = .text:0x8015D8AC; // type:function size:0x108 scope:global BuildPatternedExplodeShakeData__16CCameraShakeDataFff = .text:0x8015D9B4; // type:function size:0x108 scope:global -BuildPhazonCameraShakeData__16CCameraShakeDataFff = .text:0x8015DABC; // type:function size:0x174 scope:global +SoftBothAxesShake__16CCameraShakeDataFff = .text:0x8015DABC; // type:function size:0x174 scope:global BuildProjectileCameraShake__16CCameraShakeDataFff = .text:0x8015DC30; // type:function size:0x100 scope:global __sinit_CCameraShakeData_cpp = .text:0x8015DD30; // type:function size:0x1D4 scope:global Accept__22CScriptPickupGeneratorFR8IVisitor = .text:0x8015DF04; // type:function size:0x38 scope:global @@ -18059,7 +18059,7 @@ gPressInputs__13ControlMapper = .data:0x803D95D8; // type:object size:0x114 scop @336 = .data:0x803D97E0; // type:object size:0x60 scope:local lbl_803D9660 = .data:0x803D9840; // type:object size:0x78 scope:global __vt__11CObjectList = .data:0x803D98B8; // type:object size:0x10 scope:global -lbl_803D96E8 = .data:0x803D98C8; // type:object size:0x88 scope:global +__vt__7CPlayer = .data:0x803D98C8; // type:object size:0x88 scope:global lbl_803D9770 = .data:0x803D9950; // type:object size:0x1C scope:global lbl_803D978C = .data:0x803D996C; // type:object size:0x58 scope:global __vt__19CCollisionPrimitive = .data:0x803D99C4; // type:object size:0x2C scope:global @@ -19150,8 +19150,8 @@ lbl_80457798 = .bss:0x80457978; // type:object size:0x160 scope:local @27 = .bss:0x80457AD8; // type:object size:0xC scope:local lbl_80457908 = .bss:0x80457AE8; // type:object size:0xC0 scope:local data:float lbl_804579C8 = .bss:0x80457BA8; // type:object size:0x20 scope:local data:4byte -lbl_804579E8 = .bss:0x80457BC8; // type:object size:0x10 scope:local data:float -lbl_804579F8 = .bss:0x80457BD8; // type:object size:0x18 scope:local data:4byte +skDown$1100 = .bss:0x80457BC8; // type:object size:0xC scope:local data:float +matFilter$1103 = .bss:0x80457BD8; // type:object size:0x18 scope:local data:4byte sAllocSpace$2944 = .bss:0x80457BF0; // type:object size:0x838 scope:local sAllocSpace$2964 = .bss:0x80458428; // type:object size:0x108 scope:local sAllocSpace$2980 = .bss:0x80458530; // type:object size:0x1E58 scope:local @@ -21538,7 +21538,7 @@ lbl_805A8C70 = .sbss:0x805A8E50; // type:object size:0x4 scope:global data:4byte lbl_805A8C74 = .sbss:0x805A8E54; // type:object size:0x1 scope:global data:byte lbl_805A8C78 = .sbss:0x805A8E58; // type:object size:0x1 scope:global data:byte lbl_805A8C7C = .sbss:0x805A8E5C; // type:object size:0x4 scope:global data:4byte -lbl_805A8C80 = .sbss:0x805A8E60; // type:object size:0x1 scope:global data:byte +init$1101 = .sbss:0x805A8E60; // type:object size:0x1 scope:global data:byte lbl_805A8C81 = .sbss:0x805A8E61; // type:object size:0x1 scope:global data:byte lbl_805A8C84 = .sbss:0x805A8E64; // type:object size:0x4 scope:global data:float lbl_805A8C88 = .sbss:0x805A8E68; // type:object size:0x1 scope:global data:byte diff --git a/include/Collision/CCollisionPrimitive.hpp b/include/Collision/CCollisionPrimitive.hpp index 1c14d871..377e0989 100644 --- a/include/Collision/CCollisionPrimitive.hpp +++ b/include/Collision/CCollisionPrimitive.hpp @@ -3,17 +3,18 @@ #include "types.h" +#include "Collision/CInternalCollisionStructure.hpp" #include "Collision/CMaterialList.hpp" -#include "Kyoto/IObjectStore.hpp" #include "Kyoto/Math/CAABox.hpp" #include "Kyoto/Math/CTransform4f.hpp" +#include "Kyoto/SObjectTag.hpp" + #include "rstl/single_ptr.hpp" #include "rstl/vector.hpp" class CRayCastResult; class CCollisionInfoList; -class CInternalCollisionStructure; class CInternalRayCastStructure; class CCollisionInfo; @@ -44,7 +45,7 @@ public: virtual uint GetTableIndex() const = 0; virtual void SetMaterial(const CMaterialList& other) { x8_material = other; } - virtual const CMaterialList& GetMaterial() const; + virtual const CMaterialList& GetMaterial() const { return x8_material; } virtual CAABox CalculateAABox(const CTransform4f&) const = 0; virtual CAABox CalculateLocalAABox() const = 0; virtual FourCC GetPrimType() const = 0; @@ -62,6 +63,15 @@ public: static void InitEndColliders(); static void Uninitialize(); + static bool Collide(const CInternalCollisionStructure::CPrimDesc& prim0, + const CInternalCollisionStructure::CPrimDesc& prim1, + CCollisionInfoList& list); + static bool CollideBoolean(const CInternalCollisionStructure::CPrimDesc& prim0, + const CInternalCollisionStructure::CPrimDesc& prim1); + static bool CollideMoving(const CInternalCollisionStructure::CPrimDesc& prim0, + const CInternalCollisionStructure::CPrimDesc& prim1, + const CVector3f& dir, double& dOut, CCollisionInfo& infoOut); + private: static int sNumTypes; static bool sInitComplete; diff --git a/include/Kyoto/Audio/CSfxManager.hpp b/include/Kyoto/Audio/CSfxManager.hpp index 2ad9133c..b492081f 100644 --- a/include/Kyoto/Audio/CSfxManager.hpp +++ b/include/Kyoto/Audio/CSfxManager.hpp @@ -217,7 +217,7 @@ public: static void SfxVolume(CSfxHandle handle, uchar volume); static void SfxSpan(CSfxHandle, uchar); - static bool IsPlaying(const CSfxHandle& handle); + static bool IsPlaying(CSfxHandle handle); static void StopSound(CSfxHandle handle); static void SetChannel(ESfxChannels); diff --git a/include/Kyoto/Math/CFrustumPlanes.hpp b/include/Kyoto/Math/CFrustumPlanes.hpp index 65f5b7f3..5220976d 100644 --- a/include/Kyoto/Math/CFrustumPlanes.hpp +++ b/include/Kyoto/Math/CFrustumPlanes.hpp @@ -15,6 +15,7 @@ class CTransform4f; class CFrustumPlanes { public: + CFrustumPlanes() {} CFrustumPlanes(const CTransform4f&, float, float, float, bool, float); bool BoxInFrustumPlanes(const CAABox& box) const; diff --git a/include/Kyoto/TReservedAverage.hpp b/include/Kyoto/TReservedAverage.hpp index 647fffaa..56dfb22a 100644 --- a/include/Kyoto/TReservedAverage.hpp +++ b/include/Kyoto/TReservedAverage.hpp @@ -17,6 +17,7 @@ public: } void AddValue(const T& value); rstl::optional_object< T > GetAverage() const; + rstl::optional_object< T > GetEntry(int idx) const; }; template < typename T, int N > @@ -39,4 +40,13 @@ rstl::optional_object< T > TReservedAverage< T, N >::GetAverage() const { } } +template < typename T, int N > +inline rstl::optional_object< T > TReservedAverage< T, N >::GetEntry(int idx) const { + if (idx >= this->size()) { + return rstl::optional_object_null(); + } else { + return rstl::optional_object< T >(this->operator[](idx)); + } +} + #endif // _TRESERVEDAVERAGE diff --git a/include/MetroidPrime/CFluidPlaneManager.hpp b/include/MetroidPrime/CFluidPlaneManager.hpp index 45dd74ac..496cf286 100644 --- a/include/MetroidPrime/CFluidPlaneManager.hpp +++ b/include/MetroidPrime/CFluidPlaneManager.hpp @@ -3,12 +3,17 @@ #include "types.h" +#include "MetroidPrime/CStateManager.hpp" #include "MetroidPrime/CRippleManager.hpp" #include "MetroidPrime/TGameTypes.hpp" +#include "Kyoto/Math/CVector3f.hpp" + #include "rstl/reserved_vector.hpp" class CScriptWater; +class CStateManager; +class CVector3f; class CFluidPlaneManager { public: @@ -18,6 +23,9 @@ public: void CreateSplash(TUniqueId splasher, CStateManager& mgr, const CScriptWater& water, const CVector3f& pos, float factor, bool sfx); + float GetLastSplashDeltaTime(TUniqueId uid) const; + float GetLastRippleDeltaTime(TUniqueId uid) const; + private: class CSplashRecord { float x0_time; diff --git a/include/MetroidPrime/CGameArea.hpp b/include/MetroidPrime/CGameArea.hpp index f7bd488f..590a0718 100644 --- a/include/MetroidPrime/CGameArea.hpp +++ b/include/MetroidPrime/CGameArea.hpp @@ -93,6 +93,24 @@ public: bool operator==(const CConstChainIterator& other) const { return m_area == other.m_area; } }; + enum EOcclusionState { kOS_Occluded, kOS_Visible }; + + struct CPostConstructed { + uchar x0_pad[0xa0]; + CPVSAreaSet* xa0_pvs; + uchar xa4_pad[0x1020]; + rstl::single_ptr< CAreaFog > x10c4_areaFog; + rstl::optional_object< void* > x10c8_sclyBuf; + u32 x10d0_sclySize; + const u8* x10d4_firstMatPtr; + const CScriptAreaAttributes* x10d8_areaAttributes; + EOcclusionState x10dc_occlusionState; + uchar x10e0_pad[0x60]; + + CPostConstructed(); + ~CPostConstructed(); + }; + ~CGameArea(); const CTransform4f& IGetTM() const override; CAssetId IGetStringTableAssetId() const override; @@ -119,13 +137,23 @@ public: bool StartStreamingMainArea(); + CAssetId GetAreaAssetId() const { return x84_mrea; } + const CAreaFog* GetAreaFog() const { return x12c_postConstructed->x10c4_areaFog.get(); } + CAreaFog* AreaFog() { return x12c_postConstructed->x10c4_areaFog.get(); } + EOcclusionState GetOcclusionState() const { return x12c_postConstructed->x10dc_occlusionState; } + const rstl::vector< CWorldLight >& GetLightsA() const; + const rstl::vector< CWorldLight >& GetLightsB() const; + const CPVSAreaSet* GetAreaVisSet() const { return x12c_postConstructed->xa0_pvs; } + bool IsPostConstructed() const { return xf0_24_postConstructed; } // name? + CPostConstructed* GetPostConstructed() { return x12c_postConstructed.get(); } // name? + const CPostConstructed* GetPostConstructed() const { return x12c_postConstructed.get(); } // name? + private: void AllocNewAreaData(int, int); void CullDeadAreaRequests(); int VerifyHeader() const; int GetNumPartSizes() const; - enum EPhase { kP_LoadHeader, kP_LoadSecSizes, @@ -154,36 +182,7 @@ private: bool xf0_28_validated : 1; EPhase xf4_phase; rstl::list< rstl::rc_ptr< CDvdRequest > > xf8_loadTransactions; - -public: - enum EOcclusionState { kOS_Occluded, kOS_Visible }; - - struct CPostConstructed { - uchar x0_pad[0xa0]; - CPVSAreaSet* xa0_pvs; - uchar xa4_pad[0x1020]; - rstl::single_ptr< CAreaFog > x10c4_areaFog; - rstl::optional_object< void* > x10c8_sclyBuf; - u32 x10d0_sclySize; - const u8* x10d4_firstMatPtr; - const CScriptAreaAttributes* x10d8_areaAttributes; - EOcclusionState x10dc_occlusionState; - uchar x10e0_pad[0x60]; - - CPostConstructed(); - ~CPostConstructed(); - }; - - CAssetId GetAreaAssetId() const { return x84_mrea; } - const CAreaFog* GetAreaFog() const { return x12c_postConstructed->x10c4_areaFog.get(); } - CAreaFog* AreaFog() { return x12c_postConstructed->x10c4_areaFog.get(); } - EOcclusionState GetOcclusionState() const { return x12c_postConstructed->x10dc_occlusionState; } - const rstl::vector& GetLightsA() const; - const rstl::vector& GetLightsB() const; - const CPVSAreaSet* GetAreaVisSet() const { return x12c_postConstructed->xa0_pvs; } - -private: - rstl::vector< rstl::pair< rstl::auto_ptr, int> > x110_mreaSecBufs; + rstl::vector< rstl::pair< rstl::auto_ptr< char >, int > > x110_mreaSecBufs; int x120_unk; int x124_secCount; int x128_mreaDataOffset; diff --git a/include/MetroidPrime/CGameCollision.hpp b/include/MetroidPrime/CGameCollision.hpp index e541580f..94a83a81 100644 --- a/include/MetroidPrime/CGameCollision.hpp +++ b/include/MetroidPrime/CGameCollision.hpp @@ -22,6 +22,9 @@ public: static bool DetectDynamicCollisionBoolean(const CCollisionPrimitive&, const CTransform4f&, const TEntityList&, const CStateManager&); static void BuildAreaCollisionCache(const CStateManager& mgr, CAreaCollisionCache& cache); + static bool DetectCollisionBoolean(const CStateManager& mgr, const CCollisionPrimitive& prim, + const CTransform4f& xf, const CMaterialFilter& filter, + const TEntityList& nearList); static bool DetectCollisionBoolean_Cached(const CStateManager& mgr, CAreaCollisionCache& cache, const CCollisionPrimitive& prim, const CTransform4f& xf, const CMaterialFilter& filter, diff --git a/include/MetroidPrime/CModelData.hpp b/include/MetroidPrime/CModelData.hpp index 3562c7a9..42a997a5 100644 --- a/include/MetroidPrime/CModelData.hpp +++ b/include/MetroidPrime/CModelData.hpp @@ -66,15 +66,7 @@ public: CModelData(); CModelData(const CAnimRes&); CModelData(const CStaticRes&); - CModelData(const CModelData& other) - : x0_scale(other.x0_scale) - , xc_animData(other.xc_animData) - , x14_24_renderSorted(other.x14_24_renderSorted) - , x14_25_sortThermal(other.x14_25_sortThermal) - , x18_ambientColor(other.x18_ambientColor) - , x1c_normalModel(other.x1c_normalModel) - , x2c_xrayModel(other.x2c_xrayModel) - , x3c_infraModel(other.x3c_infraModel) {} + // CModelData(const CModelData& other); ~CModelData(); CAdvancementDeltas AdvanceAnimation(float dt, CStateManager& mgr, TAreaId aid, bool advTree); @@ -127,9 +119,9 @@ private: bool x14_24_renderSorted : 1; bool x14_25_sortThermal : 1; CColor x18_ambientColor; - rstl::optional_object< TCachedToken< CModel > > x1c_normalModel; - rstl::optional_object< TCachedToken< CModel > > x2c_xrayModel; - rstl::optional_object< TCachedToken< CModel > > x3c_infraModel; + rstl::optional_object< TLockedToken< CModel > > x1c_normalModel; + rstl::optional_object< TLockedToken< CModel > > x2c_xrayModel; + rstl::optional_object< TLockedToken< CModel > > x3c_infraModel; }; CHECK_SIZEOF(CModelData, 0x4c) diff --git a/include/MetroidPrime/CStateManager.hpp b/include/MetroidPrime/CStateManager.hpp index f8341c1c..e684069a 100644 --- a/include/MetroidPrime/CStateManager.hpp +++ b/include/MetroidPrime/CStateManager.hpp @@ -3,11 +3,9 @@ #include "types.h" -#include "Kyoto/CObjectReference.hpp" #include "Kyoto/CRandom16.hpp" #include "Kyoto/Input/CFinalInput.hpp" #include "Kyoto/Math/CFrustumPlanes.hpp" -#include "Kyoto/Math/CVector2f.hpp" #include "Kyoto/Math/CVector2i.hpp" #include "Kyoto/TOneStatic.hpp" #include "Kyoto/TToken.hpp" @@ -138,6 +136,7 @@ public: const rstl::string& HashInstanceName(CInputStream& in); bool SwapOutAllPossibleMemory(); void UpdateObjectInLists(CEntity&); + rstl::pair< int, int > CalculateScanPair() const; void BuildNearList(TEntityList& nearList, const CVector3f& pos, const CVector3f& dir, float mag, const CMaterialFilter&, const CActor*) const; @@ -193,6 +192,7 @@ public: CWorldTransManager* WorldTransManager() { return x8c4_worldTransManager.GetPtr(); } const CWorldTransManager* GetWorldTransManager() const { return x8c4_worldTransManager.GetPtr(); } EGameState GetGameState() const { return x904_gameState; } + void SetGameState(EGameState state); CRandom16* Random() const { return x900_random; } uint GetUpdateFrameIndex() const { return x8d8_updateFrameIdx; } diff --git a/include/MetroidPrime/CSteeringBehaviors.hpp b/include/MetroidPrime/CSteeringBehaviors.hpp index e0aa0a54..aac9d8fb 100644 --- a/include/MetroidPrime/CSteeringBehaviors.hpp +++ b/include/MetroidPrime/CSteeringBehaviors.hpp @@ -19,6 +19,9 @@ public: const CVector3f& v1, const CVector3f& v2, const CVector3f& v3, const CVector3f& v4, CVector3f& v5); + static CVector3f ProjectOrbitalPosition(const CVector3f& pos, const CVector3f& vel, + const CVector3f& orbitPoint, float dt, float preThinkDt); + private: float x0_; }; diff --git a/include/MetroidPrime/Cameras/CCameraManager.hpp b/include/MetroidPrime/Cameras/CCameraManager.hpp index 2ed5b463..0d66d354 100644 --- a/include/MetroidPrime/Cameras/CCameraManager.hpp +++ b/include/MetroidPrime/Cameras/CCameraManager.hpp @@ -74,7 +74,7 @@ public: void RemoveCameraShaker(int id); CTransform4f GetCurrentCameraTransform(const CStateManager& mgr) const; CVector3f GetGlobalCameraTranslation(const CStateManager& mgr) const; - bool IsInFirstPersonCamera() const; + bool IsInFPCamera() const; bool IsInterpolationCameraActive() const; bool ShouldBypassInterpolationCamera() const; void SetupInterpolation(const CTransform4f& xf, TUniqueId camId, CVector3f lookPos, diff --git a/include/MetroidPrime/Enemies/CPatterned.hpp b/include/MetroidPrime/Enemies/CPatterned.hpp index bd48af8a..28dbffa0 100644 --- a/include/MetroidPrime/Enemies/CPatterned.hpp +++ b/include/MetroidPrime/Enemies/CPatterned.hpp @@ -162,13 +162,12 @@ public: void AddToRenderer(const CFrustumPlanes&, const CStateManager&) const override; void Render(const CStateManager&) const override; bool CanRenderUnsorted(const CStateManager&) const override; - const rstl::optional_object< CAABox > GetTouchBounds() const override; + rstl::optional_object< CAABox > GetTouchBounds() const override; void Touch(CActor&, CStateManager&) override; CVector3f GetOrbitPosition(const CStateManager&) const override; CVector3f GetAimPosition(const CStateManager&, float) const override; EWeaponCollisionResponseTypes GetCollisionResponseType(const CVector3f&, const CVector3f&, - const CWeaponMode&, - int) const override; + const CWeaponMode&, int) const override; void DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) override; diff --git a/include/MetroidPrime/Factories/CScannableObjectInfo.hpp b/include/MetroidPrime/Factories/CScannableObjectInfo.hpp index 80f7b052..f360b8ed 100644 --- a/include/MetroidPrime/Factories/CScannableObjectInfo.hpp +++ b/include/MetroidPrime/Factories/CScannableObjectInfo.hpp @@ -15,6 +15,9 @@ public: static const char* GetImagePaneName(uint pane); CScannableObjectInfo(CInputStream& in, uint version); + CAssetId GetScannableObjectId() const { return x0_scannableObjectId; } + float GetTotalDownloadTime() const { return x8_totalDownloadTime; } + private: struct SBucket { CAssetId x0_texture; diff --git a/include/MetroidPrime/Player/CGameOptions.hpp b/include/MetroidPrime/Player/CGameOptions.hpp index 063e74c9..89c93e5f 100644 --- a/include/MetroidPrime/Player/CGameOptions.hpp +++ b/include/MetroidPrime/Player/CGameOptions.hpp @@ -40,11 +40,12 @@ public: void SetHelmetAlpha(int); void SetHUDLag(bool); void SetIsHintSystemEnabled(bool); - void SetInvertYAxis(bool); void ToggleControls(bool); void ResetControllerAssets(int); void SetControls(int); + void SetInvertYAxis(bool invert); + bool GetInvertYAxis() const { return x68_25_invertY; } void SetIsRumbleEnabled(bool rumble); bool GetIsRumbleEnabled() const { return x68_26_rumble; } diff --git a/include/MetroidPrime/Player/CGrappleArm.hpp b/include/MetroidPrime/Player/CGrappleArm.hpp index 57a2aef2..d4d7b216 100644 --- a/include/MetroidPrime/Player/CGrappleArm.hpp +++ b/include/MetroidPrime/Player/CGrappleArm.hpp @@ -36,10 +36,11 @@ public: void ReturnToDefault(CStateManager& mgr, float dt, bool setState); void EnterStruck(CStateManager&, float, bool, bool); void DisconnectGrappleBeam(); + void RenderGrappleBeam(const CStateManager&, const CVector3f&) const; void SetTransform(const CTransform4f& xf) { *(CTransform4f*)(&x0_pad[0x220]) = xf; } - // EArmState GetAnimState() const { return x334_animState; } + EArmState GetAnimState() const { return x334_animState; } bool GetActive() const { return x3b2_24_active; } bool BeamActive() const { return x3b2_25_beamActive; } bool IsArmMoving() const { return x3b2_27_armMoving; } diff --git a/include/MetroidPrime/Player/CMorphBall.hpp b/include/MetroidPrime/Player/CMorphBall.hpp index 1c6bc80f..b7857f36 100644 --- a/include/MetroidPrime/Player/CMorphBall.hpp +++ b/include/MetroidPrime/Player/CMorphBall.hpp @@ -1,18 +1,34 @@ #ifndef _CMORPHBALL #define _CMORPHBALL +#include "Kyoto/Audio/CSfxHandle.hpp" +#include "Kyoto/CRandom16.hpp" +#include "Kyoto/Math/CQuaternion.hpp" +#include "Kyoto/Math/CTransform4f.hpp" +#include "Kyoto/Math/CVector3f.hpp" +#include "MetroidPrime/CActor.hpp" +#include "MetroidPrime/CEntityInfo.hpp" +#include "MetroidPrime/TGameTypes.hpp" + +#include "Kyoto/Math/CFrustumPlanes.hpp" #include "Kyoto/TOneStatic.hpp" #include "Kyoto/TReservedAverage.hpp" +#include "Kyoto/TToken.hpp" #include "Collision/CCollidableSphere.hpp" #include "Collision/CCollisionInfoList.hpp" +class CActor; +class CActorLights; class CElementGen; +class CFinalInput; +class CFrustumPlanes; class CGenDescription; class CModelData; class CMorphBallShadow; class CParticleSwoosh; class CPlayer; +class CQuaternion; class CRainSplashGenerator; class CStateManager; class CSwooshDescription; @@ -28,8 +44,6 @@ public: CMorphBall(CPlayer&, float); ~CMorphBall(); - float GetBallRadius() const; - EBallBoostState GetBallBoostState() const; void SetBallBoostState(EBallBoostState state); EBombJumpState GetBombJumpState() const; @@ -39,10 +53,10 @@ public: void StopSounds(); void UpdateEffects(float dt, CStateManager& mgr); void SetBallLightActive(CStateManager& mgr, const bool active); - // GetBallToWorld__10CMorphBallCFv global - // GetBallRadius__10CMorphBallCFv global - // TakeDamage__10CMorphBallFf global - // IsProjectile__10CMorphBallCFv weak + CTransform4f GetBallToWorld() const; + float GetBallRadius() const; + void TakeDamage(float damage); + bool IsProjectile() const { return x1954_isProjectile; } // LeaveMorphBallState__10CMorphBallFR13CStateManager global // LeaveBoosting__10CMorphBallFv global // CancelBoosting__10CMorphBallFv global @@ -53,22 +67,22 @@ public: bool GetIsInHalfPipeMode() const; // DampLinearAndAngularVelocities__10CMorphBallFff global // IsClimbable__10CMorphBallCFRC14CCollisionInfo global - // FluidFXThink__10CMorphBallFQ26CActor11EFluidStateR12CScriptWaterR13CStateManager global + void FluidFXThink(CActor::EFluidState state, CScriptWater& water, CStateManager& mgr); // GetCollidableSphere__10CMorphBallCFv weak // DrawCollisionPrimitive__10CMorphBallCFv global // GetPrimitiveTransform__10CMorphBallCFv global - // TouchModel__10CMorphBallCFRC13CStateManager global - // Render__10CMorphBallCFRC13CStateManagerPC12CActorLights global + void TouchModel(const CStateManager&) const; + void Render(const CStateManager&, const CActorLights*) const; // RenderDamageEffects__10CMorphBallCFRC13CStateManagerRC12CTransform4f global // RenderSpiderBallElectricalEffects__10CMorphBallCFv global // RenderEnergyDrainEffects__10CMorphBallCFRC13CStateManager global - // RenderMorphBallTransitionFlash__10CMorphBallCFRC13CStateManager global - // GetModel__10CMorphBallCFv weak + void RenderMorphBallTransitionFlash(const CStateManager&) const; + const CModelData& GetModel() const { return *x58_ballModel.get(); } // GetBallContactSurfaceNormal__10CMorphBallCFv weak - // PreRender__10CMorphBallFR13CStateManagerRC14CFrustumPlanes global - // IsInFrustum__10CMorphBallCFRC14CFrustumPlanes global - // GetBallTouchRadius__10CMorphBallCFv global - // Touch__10CMorphBallFR6CActorR13CStateManager global + void PreRender(CStateManager&, const CFrustumPlanes&); + bool IsInFrustum(const CFrustumPlanes&) const; + float GetBallTouchRadius() const; + void Touch(CActor& actor, CStateManager& mgr); void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&); // DeleteLight__10CMorphBallFR13CStateManager global // EnterMorphBallState__10CMorphBallFR13CStateManager @@ -115,7 +129,7 @@ public: // GetTouchedHalfPipeRecently__10CMorphBallCFv global // ComputeLiftForces__10CMorphBallFRC9CVector3fRC9CVector3fRC13CStateManager global void UpdateBallDynamics(CStateManager&, float); - // BallCloseToCollision__10CMorphBallCFRC13CStateManagerf global + bool BallCloseToCollision(const CStateManager& mgr, float dist, const CMaterialFilter& filter) const; // UpdateHalfPipeStatus__10CMorphBallFR13CStateManagerf global // CalculateSurfaceToWorld__10CMorphBallCFRC9CVector3fRC9CVector3fRC9CVector3f global // UpdateMarbleDynamics__10CMorphBallFR13CStateManagerfRC9CVector3f global @@ -128,6 +142,12 @@ public: void Land(); void ResetMorphBallIceBreak(); void StopParticleWakes(); + void EnableBallShadow(); + void DisableBallShadow(); + void PreRenderBallShadow(CStateManager&); + void SetDisableSpiderBallTime(float time); + + u32 GetMorphballModelShader() const { return x5c_ballModelShader; } // name? private: struct CSpiderBallElectricityManager { diff --git a/include/MetroidPrime/Player/CPlayer.hpp b/include/MetroidPrime/Player/CPlayer.hpp index 177fa701..d4c651e7 100644 --- a/include/MetroidPrime/Player/CPlayer.hpp +++ b/include/MetroidPrime/Player/CPlayer.hpp @@ -10,7 +10,6 @@ #include "MetroidPrime/Player/CPlayerState.hpp" #include "Kyoto/TReservedAverage.hpp" -#include "Kyoto/Math/CRelAngle.hpp" #include "rstl/auto_ptr.hpp" #include "rstl/vector.hpp" @@ -67,6 +66,7 @@ class CPlayer : public CPhysicsActor, public TOneStatic< CPlayer > { }; CPlayerStuckTracker(); + ~CPlayerStuckTracker(); void AddState(EPlayerState, const CVector3f&, const CVector3f&, const CVector2f&); bool IsPlayerStuck(); void ResetStats(); @@ -168,7 +168,7 @@ public: const CMaterialList& ml); // CEntity - ~CPlayer() override; + // ~CPlayer() override; void Accept(IVisitor& visitor) override; void PreThink(float dt, CStateManager& mgr) override; void Think(float dt, CStateManager& mgr) override; @@ -215,8 +215,8 @@ public: void SetHudDisable(float staticTimer, float outSpeed = skDefaultHudFadeOutSpeed, float inSpeed = skDefaultHudFadeInSpeed); - void IncrementPhazon(); - void DecrementPhazon(); + void IncrementEnvironmentDamage(); // name? + void DecrementEnvironmentDamage(); // name? // GetMovementDirection2D__7CPlayerCFv ?? void SetOrbitTargetId(TUniqueId id, CStateManager& mgr); void TryToBreakOrbit(TUniqueId id, EOrbitBrokenType type, CStateManager& mgr); @@ -256,8 +256,8 @@ public: void UpdateVisorTransition(float dt, CStateManager& mgr); void UpdatePlayerSounds(float dt); bool ShouldSampleFailsafe(CStateManager& mgr) const; - bool IsEnergyLow(CStateManager& mgr); - bool StartSamusVoiceSfx(ushort sfx, short vol, int prio); + bool IsEnergyLow(const CStateManager& mgr) const; + const bool StartSamusVoiceSfx(ushort sfx, short vol, int prio); void UpdateVisorState(const CFinalInput& input, float dt, CStateManager& mgr); void UpdateCrosshairsState(const CFinalInput& input); ushort GetMaterialSoundUnderPlayer(CStateManager& mgr, const ushort* table, int length, @@ -314,6 +314,34 @@ public: CVector3f CalculateLeftStickEdgePosition(float strafeInput, float forwardInput) const; bool AttachActorToPlayer(TUniqueId id, bool disableGun); void DetachActorFromPlayer(); + void RenderReflectedPlayer(CStateManager& mgr); + bool HasTransitionBeamModel() const; + void RenderGun(const CStateManager& mgr, const CVector3f& pos) const; + bool GetCombatMode() const; + bool GetExplorationMode() const; + void SetScanningState(EPlayerScanState state, CStateManager& mgr); + void UpdateSlideShowUnlocking(CStateManager& mgr); // name? + bool ValidateScanning(const CFinalInput& input, CStateManager& mgr) const; + float GetTransitionAlpha(const CVector3f& camPos, float zNear) const; + void TakeDamage(bool significant, const CVector3f& location, float damage, EWeaponType type, + CStateManager& mgr); + bool WasDamaged() const; + CVector3f GetDamageLocationWR() const; + float GetPrevDamageAmount() const; + float GetDamageAmount() const; + bool ObjectInScanningRange(TUniqueId id, const CStateManager& mgr); + void AsyncLoadSuit(CStateManager& mgr); + bool IsPlayerDeadEnough() const; + void SetControlDirectionInterpolation(float time); + void ResetControlDirectionInterpolation(); + void DoThink(float dt, CStateManager& mgr); // name? + void DoPreThink(float dt, CStateManager& mgr); // name? + void SetPlayerHitWallDuringMove(); + void DoPostCameraStuff(float dt, CStateManager& mgr); // name? + float UpdateCameraBob(float dt, CStateManager& mgr); + void UpdateOrbitTarget(CStateManager& mgr); + void UpdateOrbitOrientation(CStateManager& mgr); + bool IsTransparent() const; CPlayerGun* PlayerGun() { return x490_gun.get(); } const CPlayerGun* GetPlayerGun() const { return x490_gun.get(); } @@ -356,7 +384,7 @@ public: float GetAverageSpeed() const; float GetGravity() const; - float GetAttachedActorStruggle() const { return xa28_attachedActorStruggle; } + float GetAttachedActorStruggle() const; void SetAttachedActorStruggle(float struggle) { xa28_attachedActorStruggle = struggle; } // PlayerHint @@ -557,7 +585,7 @@ private: float xa04_preThinkDt; CAssetId xa08_steamTextureId; CAssetId xa0c_iceTextureId; - uint xa10_envDmgCounter; + int xa10_envDmgCounter; float xa14_envDmgCameraShakeTimer; float xa18_phazonDamageLag; float xa1c_threatOverride; diff --git a/include/MetroidPrime/Player/CPlayerEnergyDrain.hpp b/include/MetroidPrime/Player/CPlayerEnergyDrain.hpp index 6d738fdc..8ebe1ab7 100644 --- a/include/MetroidPrime/Player/CPlayerEnergyDrain.hpp +++ b/include/MetroidPrime/Player/CPlayerEnergyDrain.hpp @@ -7,6 +7,8 @@ #include "rstl/vector.hpp" +class CStateManager; + class CEnergyDrainSource { public: CEnergyDrainSource(TUniqueId src, float intensity); @@ -26,6 +28,7 @@ public: void AddEnergyDrainSource(TUniqueId id, float intensity); void RemoveEnergyDrainSource(TUniqueId id); float GetEnergyDrainIntensity() const; + const rstl::vector< CEnergyDrainSource >& GetEnergyDrainSources() const { return x0_sources; } float GetEnergyDrainTime() const { return x10_energyDrainTime; } void ProcessEnergyDrain(const CStateManager& mgr, float dt); diff --git a/include/MetroidPrime/Player/CPlayerGun.hpp b/include/MetroidPrime/Player/CPlayerGun.hpp index 0bca5cd1..1c032604 100644 --- a/include/MetroidPrime/Player/CPlayerGun.hpp +++ b/include/MetroidPrime/Player/CPlayerGun.hpp @@ -22,8 +22,6 @@ #include "rstl/string.hpp" #include "rstl/vector.hpp" -#include "math.h" - enum EChargeState { kCS_Normal, kCS_Charged, @@ -142,7 +140,7 @@ public: void UpdateWeaponFire(float, CPlayerState&, CStateManager&); void ResetIdle(CStateManager&); void UpdateGunIdle(bool, float, float, CStateManager&); - void DamageRumble(const CVector3f&, const CStateManager&); + void DamageRumble(const CVector3f&, float damage, const CStateManager&); void TakeDamage(bool, bool, CStateManager&); void StopChargeSound(CStateManager&); void CancelFiring(CStateManager&); diff --git a/include/MetroidPrime/Player/CPlayerState.hpp b/include/MetroidPrime/Player/CPlayerState.hpp index ed4a6291..b2508371 100644 --- a/include/MetroidPrime/Player/CPlayerState.hpp +++ b/include/MetroidPrime/Player/CPlayerState.hpp @@ -1,6 +1,7 @@ #ifndef _CPLAYERSTATE #define _CPLAYERSTATE +#include "Kyoto/SObjectTag.hpp" #include "types.h" #include "MetroidPrime/CHealthInfo.hpp" @@ -117,7 +118,7 @@ public: void UpdateStaticInterference(CStateManager& stateMgr, const float& dt); void IncreaseScanTime(uint time, float val); void SetScanTime(CAssetId res, float time); - float GetScanTime(CAssetId time) const; + float GetScanTime(CAssetId res) const; bool GetIsVisorTransitioning() const; float GetVisorTransitionFactor() const; void UpdateVisorTransition(float dt); @@ -140,6 +141,9 @@ public: float CalculateHealth(); void InitializePowerUp(CPlayerState::EItemType type, int capacity); void SetPowerUp(CPlayerState::EItemType type, int capacity); + static bool IsValidScan(CAssetId res); + void SetScanCompletionRateFirst(int rate) { x180_scanCompletionRateFirst = rate; } // name? + void SetScanCompletionRateSecond(int rate) { x184_scanCompletionRateSecond = rate; } // name? void InitializeScanTimes(); @@ -151,9 +155,10 @@ public: const rstl::vector< rstl::pair< CAssetId, float > >& GetScanTimes() const { return x170_scanTimes; } + int GetLogScans() const { return x180_scanCompletionRateFirst; } + int GetTotalLogScans() const { return x184_scanCompletionRateSecond; } CHealthInfo* HealthInfo() { return &xc_health; } - const CHealthInfo& GetHealthInfo() const { return xc_health; } private: @@ -191,7 +196,7 @@ private: EPlayerSuit x20_currentSuit; rstl::reserved_vector< CPowerUp, 41 > x24_powerups; rstl::vector< rstl::pair< CAssetId, float > > x170_scanTimes; - int x180_scanCompletionRateFirst; + int x180_scanCompletionRateFirst; // pair? int x184_scanCompletionRateSecond; CStaticInterference x188_staticIntf; }; diff --git a/src/MetroidPrime/CArchMsgParmReal32.cpp b/src/MetroidPrime/CArchMsgParmReal32.cpp index aa0d80b6..28c14413 100644 --- a/src/MetroidPrime/CArchMsgParmReal32.cpp +++ b/src/MetroidPrime/CArchMsgParmReal32.cpp @@ -1,5 +1,4 @@ #include "MetroidPrime/CArchMsgParmReal32.hpp" -#include "Kyoto/Alloc/CMemory.hpp" CArchMsgParmReal32::CArchMsgParmReal32(float val) : mVal(val) {} diff --git a/src/MetroidPrime/Cameras/CCameraManager.cpp b/src/MetroidPrime/Cameras/CCameraManager.cpp index c49fd1d7..f9444f95 100644 --- a/src/MetroidPrime/Cameras/CCameraManager.cpp +++ b/src/MetroidPrime/Cameras/CCameraManager.cpp @@ -419,7 +419,7 @@ CVector3f CCameraManager::GetGlobalCameraTranslation(const CStateManager& mgr) c bool CCameraManager::IsInCinematicCamera() const { return !x4_cineCameras.empty(); } -bool CCameraManager::IsInFirstPersonCamera() const { +bool CCameraManager::IsInFPCamera() const { return x0_curCameraId == x7c_fpCamera->GetUniqueId(); } @@ -441,7 +441,7 @@ void CCameraManager::SetPlayerCamera(CStateManager& mgr, TUniqueId uid) { void CCameraManager::SetupInterpolation(const CTransform4f& xf, TUniqueId camId, CVector3f lookPos, float maxTime, float positionSpeed, float rotationSpeed, bool sinusoidal, CStateManager& mgr) { - if (IsInFirstPersonCamera()) { + if (IsInFPCamera()) { return; } x88_interpCamera->SetInterpolation(xf, lookPos, maxTime, positionSpeed, rotationSpeed, camId, diff --git a/src/MetroidPrime/Player/CPlayer.cpp b/src/MetroidPrime/Player/CPlayer.cpp index f0ae30fe..6f1b6d0d 100644 --- a/src/MetroidPrime/Player/CPlayer.cpp +++ b/src/MetroidPrime/Player/CPlayer.cpp @@ -1,47 +1,79 @@ #include "MetroidPrime/Player/CPlayer.hpp" +#include "Collision/CInternalCollisionStructure.hpp" +#include "Kyoto/CDependencyGroup.hpp" +#include "Kyoto/SObjectTag.hpp" +#include "MetroidPrime/CActor.hpp" #include "MetroidPrime/CActorParameters.hpp" +#include "MetroidPrime/CAnimData.hpp" #include "MetroidPrime/CControlMapper.hpp" +#include "MetroidPrime/CEnvFxManager.hpp" #include "MetroidPrime/CFluidPlaneCPU.hpp" +#include "MetroidPrime/CFluidPlaneManager.hpp" +#include "MetroidPrime/CGameArea.hpp" #include "MetroidPrime/CGameCollision.hpp" +#include "MetroidPrime/CHealthInfo.hpp" +#include "MetroidPrime/CModelData.hpp" +#include "MetroidPrime/CRipple.hpp" #include "MetroidPrime/CRumbleManager.hpp" +#include "MetroidPrime/CStateManager.hpp" #include "MetroidPrime/CWorld.hpp" #include "MetroidPrime/Cameras/CBallCamera.hpp" #include "MetroidPrime/Cameras/CCameraManager.hpp" +#include "MetroidPrime/Cameras/CCameraShakeData.hpp" #include "MetroidPrime/Cameras/CCinematicCamera.hpp" #include "MetroidPrime/Cameras/CFirstPersonCamera.hpp" +#include "MetroidPrime/Enemies/CMetroidBeta.hpp" +#include "MetroidPrime/Enemies/CPatterned.hpp" +#include "MetroidPrime/Factories/CScannableObjectInfo.hpp" #include "MetroidPrime/HUD/CSamusHud.hpp" #include "MetroidPrime/Player/CGameState.hpp" #include "MetroidPrime/Player/CGrappleArm.hpp" #include "MetroidPrime/Player/CMorphBall.hpp" #include "MetroidPrime/Player/CPlayerCameraBob.hpp" +#include "MetroidPrime/Player/CPlayerEnergyDrain.hpp" #include "MetroidPrime/Player/CPlayerGun.hpp" +#include "MetroidPrime/Player/CPlayerState.hpp" #include "MetroidPrime/SFX/IceCrack.h" #include "MetroidPrime/SFX/LavaWorld.h" #include "MetroidPrime/SFX/MiscSamus.h" +#include "MetroidPrime/SFX/Phazon.h" +#include "MetroidPrime/SFX/PuddleSpore.h" #include "MetroidPrime/SFX/Weapons.h" #include "MetroidPrime/ScriptObjects/CHUDBillboardEffect.hpp" +#include "MetroidPrime/ScriptObjects/CScriptAreaAttributes.hpp" #include "MetroidPrime/ScriptObjects/CScriptWater.hpp" +#include "MetroidPrime/TCastTo.hpp" +#include "MetroidPrime/TGameTypes.hpp" #include "MetroidPrime/Tweaks/CTweakBall.hpp" +#include "MetroidPrime/Tweaks/CTweakGui.hpp" #include "MetroidPrime/Tweaks/CTweakPlayer.hpp" #include "MetroidPrime/Tweaks/CTweakPlayerGun.hpp" #include "MetroidPrime/Tweaks/CTweakPlayerRes.hpp" #include "MetroidPrime/Weapons/CEnergyProjectile.hpp" +#include "Kyoto/Audio/CSfxHandle.hpp" #include "Kyoto/Audio/CSfxManager.hpp" #include "Kyoto/Audio/CStreamAudioManager.hpp" #include "Kyoto/CSimplePool.hpp" +#include "Kyoto/Graphics/CModelFlags.hpp" #include "Kyoto/Input/CRumbleVoice.hpp" +#include "Kyoto/Math/CAABox.hpp" #include "Kyoto/Math/CRelAngle.hpp" +#include "Kyoto/Math/CTransform4f.hpp" +#include "Kyoto/Math/CVector3f.hpp" #include "Kyoto/Math/CloseEnough.hpp" #include "Kyoto/Text/CStringTable.hpp" #include "Collision/CCollisionInfo.hpp" +#include "Collision/CMaterialList.hpp" #include "Collision/CRayCastResult.hpp" #include "WorldFormat/CMetroidAreaCollider.hpp" +#include "rstl/auto_ptr.hpp" #include "rstl/math.hpp" +#include "rstl/vector.hpp" static CVector3f testRayStart(0.f, 0.f, 0.f); static CVector3f testRayNormal(0.f, 0.f, 1.f); @@ -1996,19 +2028,21 @@ void CPlayer::UpdateFreeLook(float dt) { lookDeltaAngle = dt * gpTweakPlayer->GetFreeLookSnapSpeed(); } - float angleVelP = x3f0_vertFreeLookAngleVel - x3ec_freeLookPitchAngle; - float vertLookDamp = CMath::Clamp(0.f, fabsf(angleVelP / 1.0471976f), 1.f); + float angleVel = x3f0_vertFreeLookAngleVel; + angleVel -= x3ec_freeLookPitchAngle; + float vertLookDamp = CMath::Clamp(0.f, fabsf(angleVel / 1.0471976f), 1.f); float dx = lookDeltaAngle * (2.f * vertLookDamp - sinf((M_PIF / 2.f) * vertLookDamp)); - if (0.f <= angleVelP) { + if (0.f <= angleVel) { x3ec_freeLookPitchAngle += dx; } else { x3ec_freeLookPitchAngle -= dx; } - angleVelP = x3e8_horizFreeLookAngleVel - x3e4_freeLookYawAngle; + angleVel = x3e8_horizFreeLookAngleVel; + angleVel -= x3e4_freeLookYawAngle; dx = lookDeltaAngle * - CMath::Clamp(0.f, fabsf(angleVelP / gpTweakPlayer->GetHorizontalFreeLookAngleVel()), 1.f); - if (0.f <= angleVelP) { + CMath::Clamp(0.f, fabsf(angleVel / gpTweakPlayer->GetHorizontalFreeLookAngleVel()), 1.f); + if (0.f <= angleVel) { x3e4_freeLookYawAngle += dx; } else { x3e4_freeLookYawAngle -= dx; @@ -2018,3 +2052,1049 @@ void CPlayer::UpdateFreeLook(float dt) { x3e4_freeLookYawAngle = 0.f; } } + +void CPlayer::ComputeFreeLook(const CFinalInput& input) { + float lookLeft = ControlMapper::GetAnalogInput(ControlMapper::kC_LookLeft, input); + float lookRight = ControlMapper::GetAnalogInput(ControlMapper::kC_LookRight, input); + float lookUp = ControlMapper::GetAnalogInput(ControlMapper::kC_LookUp, input); + float lookDown = ControlMapper::GetAnalogInput(ControlMapper::kC_LookDown, input); + + if (gpGameState->GameOptions().GetInvertYAxis()) { + lookUp = ControlMapper::GetAnalogInput(ControlMapper::kC_LookDown, input); + lookDown = ControlMapper::GetAnalogInput(ControlMapper::kC_LookUp, input); + } + + if (!gpTweakPlayer->mStayInFreeLookWhileFiring && + (ControlMapper::GetDigitalInput(ControlMapper::kC_FireOrBomb, input) || + x304_orbitState != CPlayer::kOS_NoOrbit)) { + x3e8_horizFreeLookAngleVel = 0.f; + x3f0_vertFreeLookAngleVel = 0.f; + } else { + if (x3dc_inFreeLook) { + x3e8_horizFreeLookAngleVel = + (lookLeft - lookRight) * gpTweakPlayer->GetHorizontalFreeLookAngleVel(); + x3f0_vertFreeLookAngleVel = + (lookUp - lookDown) * gpTweakPlayer->GetVerticalFreeLookAngleVel(); + } + if (!x3de_lookAnalogHeld || !x3dd_lookButtonHeld) { + x3e8_horizFreeLookAngleVel = 0.f; + x3f0_vertFreeLookAngleVel = 0.f; + } + } + + if (gpTweakPlayer->GetHoldButtonsForFreeLook()) { + if ((gpTweakPlayer->GetTwoButtonsForFreeLook() && + (!ControlMapper::GetDigitalInput(ControlMapper::kC_LookHold1, input) || + !ControlMapper::GetDigitalInput(ControlMapper::kC_LookHold2, input))) || + (!ControlMapper::GetDigitalInput(ControlMapper::kC_LookHold1, input) && + !ControlMapper::GetDigitalInput(ControlMapper::kC_LookHold2, input))) { + x3e8_horizFreeLookAngleVel = 0.f; + x3f0_vertFreeLookAngleVel = 0.f; + } + } + + if (IsMorphBallTransitioning()) { + x3e8_horizFreeLookAngleVel = 0.f; + x3f0_vertFreeLookAngleVel = 0.f; + } +} + +void CPlayer::UpdateGunAlpha() { + switch (x498_gunHolsterState) { + case kGH_Holstered: + x494_gunAlpha = 0.f; + break; + case kGH_Holstering: + x494_gunAlpha = + CMath::Clamp(0.f, x49c_gunHolsterRemTime / gpTweakPlayerGun->GetGunHolsterTime(), 1.f); + break; + case kGH_Drawing: + x494_gunAlpha = 1.f - CMath::Clamp(0.f, x49c_gunHolsterRemTime / 0.45f, 1.f); + break; + case kGH_Drawn: + x494_gunAlpha = 1.f; + break; + } +} + +void CPlayer::AddToRenderer(const CFrustumPlanes& frustum, const CStateManager& mgr) const { + if (x2f4_cameraState != kCS_FirstPerson && x2f8_morphBallState == kMS_Morphed) { + if (x768_morphball->IsInFrustum(frustum)) { + CActor::AddToRenderer(frustum, mgr); + } else { + x768_morphball->TouchModel(mgr); + } + } else { + x490_gun->AddToRenderer(frustum, mgr); + CActor::AddToRenderer(frustum, mgr); + } +} + +void CPlayer::CalculateRenderBounds() { + if (x2f8_morphBallState == kMS_Morphed) { + float rad = x768_morphball->GetBallRadius(); + CVector3f pos = GetTranslation(); + CAABox bounds(CVector3f(pos.GetX() - rad, pos.GetY() - rad, pos.GetZ()), + CVector3f(pos.GetX() + rad, pos.GetY() + rad, pos.GetZ() + rad * 2.f)); + SetRenderBounds(bounds); + } else { + CActor::CalculateRenderBounds(); + } +} + +void CPlayer::PreRender(CStateManager& mgr, const CFrustumPlanes& frustum) { + if (x2f8_morphBallState == kMS_Morphed) { + SetCalculateLighting(false); + x768_morphball->PreRender(mgr, frustum); + } else { + SetCalculateLighting(true); + if (x2f8_morphBallState == kMS_Unmorphed) { + x490_gun->PreRender(mgr, frustum, mgr.GetCameraManager()->GetGlobalCameraTranslation(mgr)); + } + } + + if (x2f8_morphBallState == kMS_Unmorphed || mgr.GetCameraManager()->IsInCinematicCamera()) { + x768_morphball->DisableBallShadow(); + } else { + x768_morphball->EnableBallShadow(); + x768_morphball->PreRenderBallShadow(mgr); + } + + for (int i = 0; i < x730_transitionModels.size(); ++i) { + x730_transitionModels[i]->AnimationData()->PreRender(); + } + + if (x2f4_cameraState != kCS_FirstPerson) { + CActor::PreRender(mgr, frustum); + } +} + +void CPlayer::RenderReflectedPlayer(CStateManager& mgr) { + const CFrustumPlanes frustum; + switch (x2f8_morphBallState) { + case kMS_Unmorphed: + case kMS_Morphing: + case kMS_Unmorphing: + SetCalculateLighting(true); + if (x2f4_cameraState == kCS_FirstPerson) { + CActor::PreRender(mgr, frustum); + } + CPhysicsActor::Render(mgr); + if (HasTransitionBeamModel()) { + x7f0_ballTransitionBeamModel->Render(mgr, x7f4_gunWorldXf, nullptr, CModelFlags::Normal()); + } + break; + case kMS_Morphed: + x768_morphball->Render(mgr, GetActorLights()); + break; + } +} + +// TODO nonmatching +void CPlayer::Render(const CStateManager& mgr) const { + bool doRender = x2f4_cameraState != kCS_Spawned; + if (!doRender) { + if (const CCinematicCamera* cam = + TCastToConstPtr< CCinematicCamera >(mgr.GetCameraManager()->GetCurrentCamera(mgr))) { + doRender = (x2f8_morphBallState == kMS_Morphed && cam->GetFlags() & 0x40); + } + } + + if (x2f4_cameraState != kCS_FirstPerson && doRender) { + bool doTransitionRender = false; + bool doBallRender = false; + switch (x2f8_morphBallState) { + case kMS_Unmorphed: + GetModelData()->Touch(mgr, 0); + CPhysicsActor::Render(mgr); + if (HasTransitionBeamModel()) { + x7f0_ballTransitionBeamModel->Touch(mgr, 0); + x7f0_ballTransitionBeamModel->Render(mgr, x7f4_gunWorldXf, GetActorLights(), + CModelFlags::Normal()); + } + break; + case kMS_Morphing: + x768_morphball->TouchModel(mgr); + doTransitionRender = true; + doBallRender = true; + break; + case kMS_Unmorphing: + x490_gun->TouchModel(mgr); + doTransitionRender = true; + doBallRender = true; + break; + case kMS_Morphed: + GetModelData()->Touch(mgr, 0); + x768_morphball->Render(mgr, GetActorLights()); + break; + } + + if (doTransitionRender) { + CPhysicsActor::Render(mgr); + if (HasTransitionBeamModel()) { + CModelFlags flags = CModelFlags::AlphaBlended(x588_alpha).DepthCompareUpdate(true, true); + x7f0_ballTransitionBeamModel->Render(CModelData::kWM_Normal, x7f4_gunWorldXf, + GetActorLights(), flags); + } + + float morphFactor = x574_morphTime / x578_morphDuration; + float transitionAlpha; + if (morphFactor < 0.05f) { + transitionAlpha = 0.f; + } else if (morphFactor < 0.1f) { + transitionAlpha = (morphFactor - 0.05f) / 0.05f; + } else if (morphFactor < 0.8f) { + transitionAlpha = 1.f; + } else { + transitionAlpha = 1.f - (morphFactor - 0.8f) / 0.2f; + } + + const int mdsp1 = x730_transitionModels.size() + 1; + for (int i = 0; i < x730_transitionModels.size(); ++i) { + const int ni = i + 1; + const float alpha = transitionAlpha * (1.f - (ni + 1) / float(mdsp1)) * + *x71c_transitionModelAlphas.GetEntry(ni); + if (alpha != 0.f) { + CModelData& data = *x730_transitionModels[i]; + data.Render(CModelData::GetRenderingModel(mgr), *x658_transitionModelXfs.GetEntry(ni), + GetActorLights(), + CModelFlags::AlphaBlended(alpha).DepthCompareUpdate(true, true)); + if (HasTransitionBeamModel()) { + x7f0_ballTransitionBeamModel->Render( + CModelData::kWM_Normal, *x594_transisionBeamXfs.GetEntry(ni), GetActorLights(), + CModelFlags::AlphaBlended(alpha).DepthCompareUpdate(true, true)); + } + } + } + + if (doBallRender) { + float morphFactor = x574_morphTime / x578_morphDuration; + float ballAlphaStart = 0.75f; + float ballAlphaMag = 4.f; + if (x2f8_morphBallState == kMS_Unmorphing) { + ballAlphaStart = 0.875f; + morphFactor = 1.f - morphFactor; + ballAlphaMag = 8.f; + } + + if (morphFactor > ballAlphaStart) { + CModelFlags flags = + CModelFlags::AlphaBlended(ballAlphaMag * (morphFactor - ballAlphaStart)) + .UseShaderSet(x768_morphball->GetMorphballModelShader()); + x768_morphball->GetModel().Render(mgr, x768_morphball->GetBallToWorld(), GetActorLights(), + flags); + } + + if (x2f8_morphBallState == kMS_Morphing) { + if (morphFactor > 0.5f) { + float tmp = (morphFactor - 0.5f) / 0.5f; + float rotate = 1.f - tmp; + float scale = 0.75f * rotate + 1.f; + float ballAlpha; + if (tmp < 0.1f) { + ballAlpha = 0.f; + } else if (tmp < 0.2f) { + ballAlpha = (tmp - 0.1f) / 0.1f; + } else if (tmp < 0.9f) { + ballAlpha = 1.f; + } else { + ballAlpha = 1.f - (morphFactor - 0.9f) / 0.1f; + } + + const CRelAngle theta = CRelAngle::FromDegrees(360.f * rotate); + ballAlpha *= 0.5f; + if (ballAlpha > 0.f) { + CModelFlags flags = CModelFlags::Additive(ballAlpha) + .DepthCompareUpdate(true, false) + .UseShaderSet(x768_morphball->GetMorphballModelShader()); + x768_morphball->GetModel().Render(mgr, + x768_morphball->GetBallToWorld() * + CTransform4f::RotateZ(theta) * + CTransform4f::Scale(scale, scale, scale), + GetActorLights(), flags); + } + } + x768_morphball->RenderMorphBallTransitionFlash(mgr); + } + } + } + } +} + +void CPlayer::RenderGun(const CStateManager& mgr, const CVector3f& pos) const { + if (mgr.GetCameraManager()->IsInCinematicCamera()) { + return; + } + + if (x490_gun->GetGrappleArm().GetActive() && + x490_gun->GetGrappleArm().GetAnimState() != CGrappleArm::kAS_Done) { + x490_gun->GetGrappleArm().RenderGrappleBeam(mgr, pos); + } + + bool isInScanVisor = mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::kPV_Scan; + float visorTransitionFactor = mgr.GetPlayerState()->GetVisorTransitionFactor(); + bool tmp = isInScanVisor && visorTransitionFactor >= 1.f; + if (tmp != true && + ((mgr.GetCameraManager()->IsInFPCamera() && x2f4_cameraState == kCS_FirstPerson) || + (x2f8_morphBallState == kMS_Morphing && x498_gunHolsterState == kGH_Holstering))) { + x490_gun->Render(mgr, pos, CModelFlags::AlphaBlended(x494_gunAlpha)); + } +} + +bool CPlayer::GetCombatMode() const { + switch (x498_gunHolsterState) { + case kGH_Drawing: + case kGH_Drawn: + return true; + case kGH_Holstered: + case kGH_Holstering: + return false; + } + return false; +} + +bool CPlayer::GetExplorationMode() const { + switch (x498_gunHolsterState) { + case kGH_Drawing: + case kGH_Drawn: + return false; + case kGH_Holstered: + case kGH_Holstering: + return true; + default: + return false; + } +} + +void CPlayer::SetScanningState(EPlayerScanState state, CStateManager& mgr) { + if (x3a8_scanState == state) { + return; + } + + mgr.SetGameState(CStateManager::kGS_Running); + if (x3a8_scanState == kSS_ScanComplete) { + if (CActor* act = TCastToPtr< CActor >(mgr.ObjectById(x3b4_scanningObject))) { + act->OnScanStateChange(kSS_Done, mgr); + } + } + + switch (state) { + case kSS_NotScanning: + if (x3a8_scanState == kSS_Scanning || x3a8_scanState == kSS_ScanComplete) { + if (x9c6_30_newScanScanning) { + UpdateSlideShowUnlocking(mgr); + } + } + x3ac_scanningTime = 0.f; + x3b0_curScanTime = 0.f; + if (!gpTweakPlayer->mScanRetention) { + if (const CActor* act = TCastToConstPtr< CActor >(mgr.ObjectById(GetOrbitTargetId()))) { + if (act->GetMaterialList().HasMaterial(kMT_Scannable)) { + if (const CScannableObjectInfo* scanInfo = act->GetScannableObjectInfo()) { + if (mgr.GetPlayerState()->GetScanTime(scanInfo->GetScannableObjectId()) < 1.f) { + mgr.PlayerState()->SetScanTime(scanInfo->GetScannableObjectId(), 0.f); + } + } + } + } + } + x3b4_scanningObject = kInvalidUniqueId; + break; + case kSS_Scanning: + x3b4_scanningObject = GetOrbitTargetId(); + break; + case kSS_ScanComplete: + if (gpTweakPlayer->mScanFreezesGame) { + mgr.SetGameState(CStateManager::kGS_SoftPaused); + } + x3b4_scanningObject = GetOrbitTargetId(); + break; + } + + x3a8_scanState = state; +} + +// TODO nonmatching +bool CPlayer::ValidateScanning(const CFinalInput& input, CStateManager& mgr) const { + if (ControlMapper::GetDigitalInput(ControlMapper::kC_ScanItem, input)) { + CActor* act = TCastToPtr< CActor >(mgr.ObjectById(GetOrbitTargetId())); + if (x304_orbitState == CPlayer::kOS_OrbitObject && act && + act->GetMaterialList().HasMaterial(kMT_Scannable)) { + CVector3f targetToPlayer = GetTranslation() - act->GetTranslation(); + if (targetToPlayer.CanBeNormalized() && + targetToPlayer.Magnitude() < gpTweakPlayer->GetScanningRange()) { + return true; + } + } + } + return false; +} + +void CPlayer::UpdateScanningState(const CFinalInput& input, CStateManager& mgr, float dt) { + if (mgr.GetPlayerState()->GetCurrentVisor() != CPlayerState::kPV_Scan) { + SetScanningState(kSS_NotScanning, mgr); + return; + } + + if (x3a8_scanState != kSS_NotScanning && x3b4_scanningObject != GetOrbitTargetId() && + GetOrbitTargetId() != kInvalidUniqueId) { + SetScanningState(kSS_NotScanning, mgr); + } + + switch (x3a8_scanState) { + case kSS_NotScanning: + if (ValidateScanning(input, mgr)) { + if (const CActor* act = TCastToConstPtr< CActor >(mgr.ObjectById(GetOrbitTargetId()))) { + const CScannableObjectInfo* scanInfo = act->GetScannableObjectInfo(); + float scanTime = mgr.GetPlayerState()->GetScanTime(scanInfo->GetScannableObjectId()); + if (scanTime >= 1.f) { + x9c6_30_newScanScanning = false; + scanTime = 1.f; + } else { + x9c6_30_newScanScanning = true; + } + + SetScanningState(kSS_Scanning, mgr); + x3ac_scanningTime = scanTime * scanInfo->GetTotalDownloadTime(); + x3b0_curScanTime = 0.f; + } + } + break; + case kSS_Scanning: + if (ValidateScanning(input, mgr)) { + if (const CActor* act = TCastToConstPtr< CActor >(mgr.ObjectById(GetOrbitTargetId()))) { + if (const CScannableObjectInfo* scanInfo = act->GetScannableObjectInfo()) { + float totalTime = scanInfo->GetTotalDownloadTime(); + x3ac_scanningTime = rstl::min_val(x3ac_scanningTime + dt, totalTime); + x3b0_curScanTime += dt; + mgr.PlayerState()->SetScanTime(scanInfo->GetScannableObjectId(), + x3ac_scanningTime / totalTime); + if (x3ac_scanningTime >= totalTime && + x3b0_curScanTime >= gpTweakGui->GetScanSidesStartTime()) { + SetScanningState(kSS_ScanComplete, mgr); + } + } + } else { + SetScanningState(kSS_NotScanning, mgr); + } + } else { + SetScanningState(kSS_NotScanning, mgr); + } + break; + case kSS_ScanComplete: + if (!ValidateScanning(input, mgr)) { + SetScanningState(kSS_NotScanning, mgr); + } + break; + } +} + +void CPlayer::Touch(CActor& actor, CStateManager& mgr) { + if (x2f8_morphBallState != kMS_Morphed) { + return; + } + + x768_morphball->Touch(actor, mgr); +} + +rstl::optional_object< CAABox > CPlayer::GetTouchBounds() const { + if (x2f8_morphBallState == kMS_Morphed) { + const float ballTouchRad = x768_morphball->GetBallTouchRadius(); + const float negBallTouchRad = -ballTouchRad; + const CVector3f ballCenter = + GetTranslation() + CVector3f(0.f, 0.f, x768_morphball->GetBallRadius()); + return CAABox(ballCenter + CVector3f(negBallTouchRad, negBallTouchRad, negBallTouchRad), + ballCenter + CVector3f(ballTouchRad, ballTouchRad, ballTouchRad)); + } else { + return GetBoundingBox(); + } +} + +void CPlayer::SetHudDisable(float staticTimer, float outSpeed, float inSpeed) { + x740_staticTimer = staticTimer; + x744_staticOutSpeed = outSpeed; + x748_staticInSpeed = inSpeed; + + if (x744_staticOutSpeed != 0.f) { + return; + } + + if (x740_staticTimer == 0.f) { + x74c_visorStaticAlpha = 1.f; + } else { + x74c_visorStaticAlpha = 0.f; + } +} + +bool CPlayer::CanEnterMorphBallState(CStateManager& mgr, float f1) const { +#if !NONMATCHING + TEntityList nearList; +#endif + if (x3b8_grappleState != kGS_None || + (IsUnderBetaMetroidAttack(mgr) && x2f8_morphBallState == kMS_Unmorphed)) { + return false; + } + if (!x9c4_27_canEnterMorphBall) { + return false; + } + return true; +} + +// TODO nonmatching +bool CPlayer::CanLeaveMorphBallState(CStateManager& mgr, CVector3f& pos) const { + if (x768_morphball->IsProjectile() || !x590_leaveMorphballAllowed || + (IsUnderBetaMetroidAttack(mgr) && x2f8_morphBallState == kMS_Morphed)) { + return false; + } + + if (!x9c4_28_canLeaveMorphBall) { + return false; + } + + TEntityList nearList; + CMaterialFilter filter = CMaterialFilter::MakeInclude(CMaterialList(kMT_Solid)); + const CVector3f& max = x2d8_fpBounds.GetMaxPoint() + CVector3f(1.f, 1.f, 1.f) + GetTranslation(); + const CVector3f& min = x2d8_fpBounds.GetMinPoint() - CVector3f(1.f, 1.f, 1.f) + GetTranslation(); + mgr.BuildColliderList(nearList, *this, CAABox(min, max)); + const CAABox& baseAABB = GetBaseBoundingBox(); + const CVector3f& playerPos = GetTranslation(); + pos = CVector3f::Zero(); + + for (int i = 0; i < 8; ++i) { + CCollidableAABox cAABB( + CAABox(baseAABB.GetMinPoint() + pos + playerPos, baseAABB.GetMaxPoint() + pos + playerPos), + CMaterialList()); + if (!CGameCollision::DetectCollisionBoolean(mgr, cAABB, CTransform4f::Identity(), filter, + nearList)) { + return true; + } + pos[kDZ] += 0.1f; + } + + return false; +} + +bool CPlayer::IsUnderBetaMetroidAttack(CStateManager& mgr) const { + if (x274_energyDrain.GetEnergyDrainIntensity() > 0.f) { + const rstl::vector< CEnergyDrainSource >& sources = x274_energyDrain.GetEnergyDrainSources(); + for (rstl::vector< CEnergyDrainSource >::const_iterator it = sources.begin(); + it != sources.end(); ++it) { + if (CPatterned::CastTo(TPatternedCast< CMetroidBeta >( + const_cast< CEntity* >(mgr.ObjectById(it->GetEnergyDrainSourceId()))))) { + return true; + } + } + } + + return false; +} + +float CPlayer::GetTransitionAlpha(const CVector3f& camPos, float zNear) const { + float zLimit = + (x2d8_fpBounds.GetMaxPoint().GetX() - x2d8_fpBounds.GetMinPoint().GetX()) * 0.5f + zNear; + float zStart = 1.f + zLimit; + float dist = (camPos - GetEyePosition()).Magnitude(); + + float out = 0.f; + if (dist >= zLimit && dist <= zStart) { + out = (dist - zLimit) / (zStart - zLimit); + } else if (dist > zStart) { + out = 1.f; + } + return out; +} + +CHealthInfo* CPlayer::HealthInfo(CStateManager& mgr) { return mgr.PlayerState()->HealthInfo(); } + +void CPlayer::Accept(IVisitor& visitor) { visitor.Visit(*this); } + +void CPlayer::TakeDamage(bool significant, const CVector3f& location, float damage, + EWeaponType type, CStateManager& mgr) { + if (!significant) { + return; + } + + if (damage >= 0.f) { + x570_immuneTimer = 0.5f; + x55c_damageAmt = damage; + x560_prevDamageAmt = (type == kWT_AI && damage == 0.00002f) ? 10.f : damage; + x564_damageLocation = location; + x558_wasDamaged = true; + + short suitDamageSfx = 0; + short damageLoopSfx = 0; + short damageSamusVoiceSfx = 0; + bool doRumble = false; + + switch (type) { + case kWT_Phazon: + case kWT_OrangePhazon: + damageLoopSfx = SFXphz_damage_lp; + damageSamusVoiceSfx = SFXsam_vox_damage_phazon; + break; + case kWT_PoisonWater: + damageLoopSfx = SFXsam_damage_poison_lp; + damageSamusVoiceSfx = SFXsam_vox_damage_poison; + break; + case kWT_Lava: + damageLoopSfx = SFXpds_lava_damage_lp; + case kWT_Heat: + damageSamusVoiceSfx = SFXsam_vox_damage_heat; + break; + default: + if (x2f8_morphBallState == kMS_Unmorphed) { + if (damage > 30.f) { + damageSamusVoiceSfx = SFXsam_vox_damage30; + } else if (damage > 15.f) { + damageSamusVoiceSfx = SFXsam_vox_damage15; + } else { + damageSamusVoiceSfx = SFXsam_vox_damage; + } + suitDamageSfx = SFXsam_suit_damage; + } else { + if (damage > 30.f) { + suitDamageSfx = SFXsam_ball_damage30; + } else if (damage > 15.f) { + suitDamageSfx = SFXsam_ball_damage15; + } else { + suitDamageSfx = SFXsam_ball_damage; + } + } + break; + } + + if (damageSamusVoiceSfx != 0 && x774_samusVoiceTimeout <= 0.f) { + StartSamusVoiceSfx(damageSamusVoiceSfx, 127, 8); + x774_samusVoiceTimeout = mgr.Random()->Range(3.f, 4.f); + doRumble = true; + } + + bool playingLoopSFx = CSfxHandle::NullHandle() != x770_damageLoopSfx; + if (damageLoopSfx && !x9c7_24_noDamageLoopSfx && xa2c_damageLoopSfxDelayTicks >= 2) { + if (!playingLoopSFx || x788_damageLoopSfxId != damageLoopSfx) { + if (playingLoopSFx && x788_damageLoopSfxId != damageLoopSfx) { + CSfxManager::SfxStop(x770_damageLoopSfx); + } + x770_damageLoopSfx = + CSfxManager::SfxStart(damageLoopSfx, 127, 64, false, CSfxManager::kMedPriority, true); + x788_damageLoopSfxId = damageLoopSfx; + } + x784_damageSfxTimer = 0.5f; + } + + if (suitDamageSfx != 0) { + if (playingLoopSFx) { + CSfxManager::SfxStop(x770_damageLoopSfx); + x770_damageLoopSfx.Clear(); + } + CSfxManager::SfxStart(suitDamageSfx); + x788_damageLoopSfxId = suitDamageSfx; + xa2c_damageLoopSfxDelayTicks = 0; + doRumble = true; + } + + if (doRumble) { + if (x2f8_morphBallState == kMS_Unmorphed) { + x490_gun->DamageRumble(location, damage, mgr); + } + mgr.GetRumbleManager()->Rumble(mgr, kRFX_PlayerBump, CMath::Limit(x55c_damageAmt / 25.f, 1.f), + kRP_One); + } + + if (x2f8_morphBallState != kMS_Unmorphed) { + x768_morphball->TakeDamage(x55c_damageAmt); + x768_morphball->SetDisableSpiderBallTime(0.4f); + } + } + + if (x3b8_grappleState != kGS_None) { + BreakGrapple(kOB_DamageOnGrapple, mgr); + } +} + +bool CPlayer::WasDamaged() const { return x558_wasDamaged; } + +float CPlayer::GetDamageAmount() const { return x55c_damageAmt; } + +float CPlayer::GetPrevDamageAmount() const { return x560_prevDamageAmt; } + +CVector3f CPlayer::GetDamageLocationWR() const { return x564_damageLocation; } + +void CPlayer::FluidFXThink(EFluidState state, CScriptWater& water, CStateManager& mgr) { + if (x2f8_morphBallState == kMS_Morphed) { + x768_morphball->FluidFXThink(state, water, mgr); + if (state == kFS_InFluid) { + x9c5_30_selectFluidBallSound = true; + } + } else if (x2f8_morphBallState != kMS_Unmorphed) { + if (mgr.GetFluidPlaneManager()->GetLastSplashDeltaTime(GetUniqueId()) >= 0.2f) { + CVector3f position(GetTranslation().GetX(), GetTranslation().GetY(), + water.GetTriggerBoundsWR().GetMaxPoint().GetZ()); + mgr.FluidPlaneManager()->CreateSplash(GetUniqueId(), mgr, water, position, 0.1f, + state == kFS_EnteredFluid); + } + } else { + if (mgr.GetFluidPlaneManager()->GetLastSplashDeltaTime(GetUniqueId()) >= 0.2f) { + CVector3f posOffset = x50c_moveDir; + if (posOffset.CanBeNormalized()) { + posOffset = posOffset.AsNormalized() * CVector3f(1.2f, 1.2f, 0.f); + } + switch (state) { + case kFS_EnteredFluid: { + bool doSplash = true; + if (x4fc_flatMoveSpeed > 12.5f) { + CVector3f lookDir = GetTransform().GetColumn(kDY).DropZ().AsNormalized(); + if (CVector3f::Dot(lookDir, CVector3f(GetDampedClampedVelocityWR().GetX(), + GetDampedClampedVelocityWR().GetY(), 0.f) + .AsNormalized()) > 0.75f) { + doSplash = false; + } + } + if (doSplash) { + CVector3f position(GetTranslation().GetX() + posOffset.GetX(), + GetTranslation().GetY() + posOffset.GetY(), + water.GetTriggerBoundsWR().GetMaxPoint().GetZ()); + mgr.FluidPlaneManager()->CreateSplash(GetUniqueId(), mgr, water, position, 0.3f, true); + if (water.GetFluidPlane().GetFluidType() == CFluidPlane::kFT_NormalWater) { + float velMag = mgr.GetPlayer()->GetVelocityWR().Magnitude() / 10.f; + mgr.EnvFxManager()->SetSplashRate(10.f * rstl::max_val(1.f, velMag)); + } + } + break; + } + case kFS_InFluid: { + if (GetVelocityWR().Magnitude() > 1.f && + mgr.GetFluidPlaneManager()->GetLastRippleDeltaTime(GetUniqueId()) >= 0.2f) { + CVector3f position(GetTranslation().GetX(), GetTranslation().GetY(), + water.GetTriggerBoundsWR().GetMaxPoint().GetZ()); + water.FluidPlane().AddRipple(CRipple::kDefaultScale, GetUniqueId(), position, water, mgr); + } + break; + } + case kFS_LeftFluid: { + CVector3f position(GetTranslation().GetX() + posOffset.GetX(), + GetTranslation().GetY() + posOffset.GetY(), + water.GetTriggerBoundsWR().GetMaxPoint().GetZ()); + mgr.FluidPlaneManager()->CreateSplash(GetUniqueId(), mgr, water, position, 0.15f, true); + break; + } + default: + break; + } + } + } +} + +// TODO nonmatching +bool CPlayer::ObjectInScanningRange(TUniqueId id, const CStateManager& mgr) { + if (const CActor* act = TCastToConstPtr< CActor >(mgr.GetObjectById(id))) { + CVector3f delta = act->GetTranslation() - GetTranslation(); + if (delta.CanBeNormalized() && delta.Magnitude() < gpTweakPlayer->GetScanningRange()) { + return true; + } + } + return false; +} + +CVector3f CPlayer::GetAimPosition(const CStateManager& mgr, float dt) const { + CVector3f ret = GetTranslation(); + if (dt > 0.f) { + if (x304_orbitState == CPlayer::kOS_NoOrbit) { + ret += PredictMotion(dt).GetTranslation(); + } else { + CVector3f vel = GetVelocityWR(); + ret = CSteeringBehaviors::ProjectOrbitalPosition(GetTranslation(), vel, GetOrbitPoint(), dt, + xa04_preThinkDt); + } + } + + if (x2f8_morphBallState == kMS_Morphed) { + ret[kDZ] += gpTweakPlayer->mPlayerBallHalfExtent; + } else { + ret[kDZ] += GetEyeHeight(); + } + + return ret; +} + +CVector3f CPlayer::GetHomingPosition(const CStateManager& mgr, float dt) const { + if (dt > 0.f) { + return GetTranslation() + PredictMotion(dt).GetTranslation(); + } + return GetTranslation(); +} + +const CDamageVulnerability* CPlayer::GetDamageVulnerability(const CVector3f& v1, + const CVector3f& v2, + const CDamageInfo& info) const { + if (x2f8_morphBallState == kMS_Morphed && x570_immuneTimer > 0.f && !info.NoImmunity()) { + return &CDamageVulnerability::ImmuneVulnerabilty(); + } + return &CDamageVulnerability::NormalVulnerabilty(); +} + +const CDamageVulnerability* CPlayer::GetDamageVulnerability() const { + const CDamageInfo info(CWeaponMode(kWT_Power, false, false, false), 0.f, 0.f, 0.f); + return GetDamageVulnerability(CVector3f::Zero(), CVector3f::Up(), info); +} + +bool CPlayer::CanRenderUnsorted(const CStateManager& mgr) const { return false; } + +bool CPlayer::HasTransitionBeamModel() const { + return !x7f0_ballTransitionBeamModel.null() && !x7f0_ballTransitionBeamModel->IsNull(); +} + +void CPlayer::LoadAnimationTokens() { + TLockedToken< CDependencyGroup > transGroup = gpSimplePool->GetObj("BallTransition_DGRP"); + const rstl::vector< SObjectTag >& tags = transGroup->GetObjectTagVector(); + x25c_ballTransitionsRes.reserve(tags.size()); + for (rstl::vector< SObjectTag >::const_iterator it = tags.begin(); it != tags.end(); ++it) { + if (it->GetType() == 'CMDL' || it->GetType() == 'CSKR' || it->GetType() == 'TXTR') { + continue; + } + CToken token = gpSimplePool->GetObj(*it); + token.Lock(); + x25c_ballTransitionsRes.push_back(token); + } +} + +void CPlayer::AsyncLoadSuit(CStateManager& mgr) { x490_gun->AsyncLoadSuit(mgr); } + +bool CPlayer::IsPlayerDeadEnough() const { + switch (x2f8_morphBallState) { + case kMS_Unmorphed: + return x9f4_deathTime > 2.5f; + case kMS_Morphed: + return x9f4_deathTime > 6.f; + case kMS_Morphing: + case kMS_Unmorphing: + return false; + } + return false; +} + +void CPlayer::SetControlDirectionInterpolation(float time) { + x9c6_25_interpolatingControlDir = true; + x9f8_controlDirInterpTime = 0.f; + x9fc_controlDirInterpDur = time; +} + +void CPlayer::ResetControlDirectionInterpolation() { + x9c6_25_interpolatingControlDir = false; + x9f8_controlDirInterpTime = 0.f; +} + +void CPlayer::DoThink(float dt, CStateManager& mgr) { + Think(dt, mgr); + if (CEntity* ent = mgr.ObjectById(xa00_deathPowerBomb)) { + ent->Think(dt, mgr); + } +} + +void CPlayer::DoPreThink(float dt, CStateManager& mgr) { + PreThink(dt, mgr); + if (CEntity* ent = mgr.ObjectById(xa00_deathPowerBomb)) { + ent->PreThink(dt, mgr); + } +} + +void CPlayer::IncrementEnvironmentDamage() { + if (xa10_envDmgCounter == 0) { + xa14_envDmgCameraShakeTimer = 0.f; + } + xa10_envDmgCounter++; +} + +void CPlayer::DecrementEnvironmentDamage() { + if (xa10_envDmgCounter != 0) { + xa10_envDmgCounter--; + } +} + +void CPlayer::UpdateEnvironmentDamageCameraShake(float dt, CStateManager& mgr) { + xa2c_damageLoopSfxDelayTicks = rstl::min_val(xa2c_damageLoopSfxDelayTicks + 1, 2); + if (xa10_envDmgCounter == 0) { + return; + } + + if (xa14_envDmgCameraShakeTimer == 0.f) { + CCameraShakeData data = CCameraShakeData::SoftBothAxesShake(1.f, 0.075f); + mgr.CameraManager()->AddCameraShaker(data, false); + } + xa14_envDmgCameraShakeTimer += dt; + if (xa14_envDmgCameraShakeTimer > 2.f) { + xa14_envDmgCameraShakeTimer = 0.f; + } +} + +// TODO nonmatching +void CPlayer::UpdatePhazonDamage(float dt, CStateManager& mgr) { + TAreaId areaId = GetCurrentAreaId(); + if (areaId == kInvalidAreaId || !mgr.GetWorld()->GetAreaAlways(areaId).IsPostConstructed()) { + return; + } + + bool touchingPhazon = false; + EPhazonType phazonType; + if (const CScriptAreaAttributes* attr = + mgr.GetWorld()->GetAreaAlways(areaId).GetPostConstructed()->x10d8_areaAttributes) { + phazonType = attr->GetPhazonType(); + } else { + phazonType = kPT_None; + } + + if (phazonType == kPT_Orange || + (!mgr.GetPlayerState()->HasPowerUp(CPlayerState::kIT_PhazonSuit) && phazonType == kPT_Blue)) { + CMaterialFilter filter = CMaterialFilter::MakeInclude(CMaterialList(kMT_Phazon)); + if (x2f8_morphBallState == kMS_Morphed) { + touchingPhazon = x768_morphball->BallCloseToCollision(mgr, 2.9f, filter); + } else { + CMaterialList primMaterial(kMT_Player, kMT_Solid); + CCollidableSphere prim( + CSphere(GetCollisionPrimitive()->CalculateAABox(GetTransform()).GetCenterPoint(), 4.25f), + primMaterial); + TEntityList nearList; + mgr.BuildColliderList(nearList, *this, prim.CalculateLocalAABox()); + if (CGameCollision::DetectStaticCollisionBoolean(mgr, prim, CTransform4f::Identity(), + filter)) { + touchingPhazon = true; + } else { + for (TEntityList::iterator id = nearList.begin(); id != nearList.end(); ++id) { + if (const CPhysicsActor* act = TCastToConstPtr< CPhysicsActor >(mgr.GetObjectById(*id))) { + if (CCollisionPrimitive::CollideBoolean( + CInternalCollisionStructure::CPrimDesc(prim, filter, CTransform4f::Identity()), + CInternalCollisionStructure::CPrimDesc(*act->GetCollisionPrimitive(), + CMaterialFilter::GetPassEverything(), + act->GetPrimitiveTransform()))) { + touchingPhazon = true; + break; + } + } + } + } + } + } + + if (touchingPhazon) { + xa18_phazonDamageLag += dt; + xa18_phazonDamageLag = rstl::min_val(3.f, xa18_phazonDamageLag); + if (xa18_phazonDamageLag > 0.2f) { + float damage = (xa18_phazonDamageLag - 0.2f) / 3.f * 60.f * dt; + CDamageInfo dInfo(CWeaponMode(phazonType == kPT_Orange ? kWT_OrangePhazon : kWT_Phazon), + damage, 0.f, 0.f); + mgr.ApplyDamage( + kInvalidUniqueId, GetUniqueId(), kInvalidUniqueId, dInfo, + CMaterialFilter::MakeIncludeExclude(CMaterialList(kMT_Solid), CMaterialList()), + CVector3f::Zero()); + } + } else { + xa18_phazonDamageLag -= dt; + xa18_phazonDamageLag = rstl::min_val(0.2f, xa18_phazonDamageLag); + xa18_phazonDamageLag = rstl::max_val(0.f, xa18_phazonDamageLag); + } + + xa1c_threatOverride = rstl::min_val(xa18_phazonDamageLag / 0.2f, 1.f); +} + +void CPlayer::DoSfxEffects(CSfxHandle sfx) { + if (!CheckSubmerged()) { + return; + } + + CSfxManager::PitchBend(sfx, 0); +} + +void CPlayer::SetPlayerHitWallDuringMove() { + x9c5_29_hitWall = true; + x2d0_curAcceleration = 1; +} + +void CPlayer::DoPostCameraStuff(float dt, CStateManager& mgr) { + UpdateArmAndGunTransforms(dt, mgr); + + float grappleSwingT; + if (x3b8_grappleState != kGS_Swinging) { + grappleSwingT = 0.f; + } else { + grappleSwingT = x3bc_grappleSwingTimer / gpTweakPlayer->mGrappleSwingPeriod; + } + + float cameraBobT = 0.f; + if (mgr.GetCameraManager()->IsInCinematicCamera()) { + *x76c_cameraBob = CPlayerCameraBob(CPlayerCameraBob::kCBT_One); + } else { + cameraBobT = UpdateCameraBob(dt, mgr); + } + + x490_gun->Update(grappleSwingT, cameraBobT, dt, mgr); + UpdateOrbitTarget(mgr); + UpdateOrbitOrientation(mgr); +} + +const bool CPlayer::StartSamusVoiceSfx(const ushort sfx, const short vol, int prio) { + bool started = true; + if (x2f8_morphBallState == kMS_Morphed) { + return false; + } + + if (x77c_samusVoiceSfx) { + if (CSfxManager::IsPlaying(x77c_samusVoiceSfx)) { + started = false; + if (prio > x780_samusVoicePriority) { + CSfxManager::SfxStop(x77c_samusVoiceSfx); + started = true; + } + } + } + + if (started) { + x77c_samusVoiceSfx = CSfxManager::SfxStart(sfx, vol); + x780_samusVoicePriority = prio; + } + + return started; +} + +float CPlayer::GetAttachedActorStruggle() const { return xa28_attachedActorStruggle; } + +void CPlayer::UpdateSlideShowUnlocking(CStateManager& mgr) { + const CActor* act = TCastToConstPtr< CActor >(mgr.ObjectById(GetOrbitTargetId())); + + if (!act) { + return; + } + + if (!act->GetMaterialList().HasMaterial(kMT_Scannable)) { + return; + } + + const CScannableObjectInfo* scanInfo = act->GetScannableObjectInfo(); + if (!scanInfo) { + return; + } + + if (mgr.PlayerState()->GetScanTime(scanInfo->GetScannableObjectId()) >= 1.f && + CPlayerState::IsValidScan(scanInfo->GetScannableObjectId())) { + rstl::pair< int, int > scanCompletion = mgr.CalculateScanPair(); + extern CAssetId UpdatePersistentScanPercent(int, int, int); // TODO: CSlideShow + CAssetId message = UpdatePersistentScanPercent(mgr.PlayerState()->GetLogScans(), + scanCompletion.first, scanCompletion.second); + if (message != kInvalidAssetId) { + mgr.ShowPausedHUDMemo(message, 0.f); + } + mgr.PlayerState()->SetScanCompletionRateFirst(scanCompletion.first); + mgr.PlayerState()->SetScanCompletionRateSecond(scanCompletion.second); + } +} + +bool CPlayer::IsEnergyLow(const CStateManager& mgr) const { + CHealthInfo healthInfo = *GetHealthInfo(mgr); + int numEnergyTanks = mgr.GetPlayerState()->GetItemCapacity(CPlayerState::kIT_EnergyTanks); + float lowThreshold = numEnergyTanks >= 4 ? 100.f : 30.f; + return healthInfo.GetHP() < lowThreshold; +} + +bool CPlayer::IsTransparent() const { return x588_alpha < 1.f; } + +// TODO nonmatching & should be implicit +CPlayer::CPlayerStuckTracker::~CPlayerStuckTracker() {} diff --git a/src/MetroidPrime/Player/CPlayerGun.cpp b/src/MetroidPrime/Player/CPlayerGun.cpp index 03a34f8d..d6a2faf6 100644 --- a/src/MetroidPrime/Player/CPlayerGun.cpp +++ b/src/MetroidPrime/Player/CPlayerGun.cpp @@ -1013,7 +1013,7 @@ void CPlayerGun::CMotionState::Update(bool firing, float dt, CTransform4f& xf, C } } -void CPlayerGun::DamageRumble(const CVector3f&, const CStateManager&) {} +void CPlayerGun::DamageRumble(const CVector3f&, float damage, const CStateManager&) {} void CPlayerGun::TakeDamage(bool bigStrike, bool notFromMetroid, CStateManager& mgr) { const CPlayer& player = *mgr.GetPlayer(); diff --git a/src/MetroidPrime/ScriptObjects/CScriptSpecialFunction.cpp b/src/MetroidPrime/ScriptObjects/CScriptSpecialFunction.cpp index 8030a7eb..01dda6fb 100644 --- a/src/MetroidPrime/ScriptObjects/CScriptSpecialFunction.cpp +++ b/src/MetroidPrime/ScriptObjects/CScriptSpecialFunction.cpp @@ -514,7 +514,7 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId case kSF_AreaDamage: { if ((msg == kSM_Deleted || msg == kSM_Deactivate) && x1e4_31_inAreaDamage) { x1e4_31_inAreaDamage = false; - mgr.Player()->DecrementPhazon(); + mgr.Player()->DecrementEnvironmentDamage(); mgr.SetIsFullThreat(false); } break; @@ -1037,7 +1037,7 @@ void CScriptSpecialFunction::ThinkAreaDamage(float dt, CStateManager& mgr) { if (x1e4_31_inAreaDamage) { if (!inArea || immune) { x1e4_31_inAreaDamage = false; - mgr.Player()->DecrementPhazon(); + mgr.Player()->DecrementEnvironmentDamage(); SendScriptMsgs(kSS_Exited, mgr, kSM_None); mgr.SetIsFullThreat(false); return; @@ -1046,7 +1046,7 @@ void CScriptSpecialFunction::ThinkAreaDamage(float dt, CStateManager& mgr) { return; } else { x1e4_31_inAreaDamage = true; - mgr.Player()->IncrementPhazon(); + mgr.Player()->IncrementEnvironmentDamage(); SendScriptMsgs(kSS_Entered, mgr, kSM_None); mgr.SetIsFullThreat(true); } diff --git a/src/MetroidPrime/ScriptObjects/CScriptSteam.cpp b/src/MetroidPrime/ScriptObjects/CScriptSteam.cpp index f4f2de5f..711882a8 100644 --- a/src/MetroidPrime/ScriptObjects/CScriptSteam.cpp +++ b/src/MetroidPrime/ScriptObjects/CScriptSteam.cpp @@ -49,10 +49,6 @@ void CScriptSteam::Think(float dt, CStateManager& mgr) { if (x148_28_playerTriggerProc && mgr.GetCameraManager()->GetFluidCounter() == 0) { CVector3f eyePos = mgr.GetPlayer()->GetEyePosition(); const float mag = (GetTranslation() - eyePos).Magnitude(); - // const float distance = - // (mag >= GetMaxDist() - // ? 0.f - // : CMath::FastCosR((mag * 1.5707964f /* 90 deg */) * GetOOMaxDist()) * GetStrength()); float distance; if (mag >= GetMaxDist()) { distance = 0.f; diff --git a/src/MetroidPrime/ScriptObjects/CScriptTrigger.cpp b/src/MetroidPrime/ScriptObjects/CScriptTrigger.cpp index 27696d81..28d8774b 100644 --- a/src/MetroidPrime/ScriptObjects/CScriptTrigger.cpp +++ b/src/MetroidPrime/ScriptObjects/CScriptTrigger.cpp @@ -82,7 +82,7 @@ void CScriptTrigger::Touch(CActor& act, CStateManager& mgr) { pl = mgr.Player(); if (x148_29_didPhazonDamage) { - pl->DecrementPhazon(); + pl->DecrementEnvironmentDamage(); x148_29_didPhazonDamage = false; } if (!x100_damageInfo.HasNoDamage()) { @@ -94,7 +94,7 @@ void CScriptTrigger::Touch(CActor& act, CStateManager& mgr) { } } if (phazonHurt) { - pl->IncrementPhazon(); + pl->IncrementEnvironmentDamage(); x148_29_didPhazonDamage = true; } } @@ -156,7 +156,7 @@ void CScriptTrigger::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CS CPlayer* player = mgr.Player(); if (x148_29_didPhazonDamage) { - player->DecrementPhazon(); + player->DecrementEnvironmentDamage(); x148_29_didPhazonDamage = false; } @@ -171,7 +171,7 @@ void CScriptTrigger::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CS CPlayer* player = mgr.Player(); if (x148_29_didPhazonDamage) { - player->DecrementPhazon(); + player->DecrementEnvironmentDamage(); x148_29_didPhazonDamage = false; } @@ -215,7 +215,7 @@ void CScriptTrigger::UpdateInhabitants(float dt, CStateManager& mgr) { if (x148_28_playerTriggerProc) { x148_28_playerTriggerProc = false; if (x148_29_didPhazonDamage) { - mgr.Player()->DecrementPhazon(); + mgr.Player()->DecrementEnvironmentDamage(); x148_29_didPhazonDamage = false; } @@ -266,7 +266,7 @@ void CScriptTrigger::UpdateInhabitants(float dt, CStateManager& mgr) { if (mgr.GetPlayer()->GetUniqueId() == tmpId && x148_28_playerTriggerProc) { x148_28_playerTriggerProc = false; if (x148_29_didPhazonDamage) { - mgr.Player()->DecrementPhazon(); + mgr.Player()->DecrementEnvironmentDamage(); x148_29_didPhazonDamage = false; } @@ -282,7 +282,7 @@ void CScriptTrigger::UpdateInhabitants(float dt, CStateManager& mgr) { if (mgr.GetPlayer()->GetUniqueId() == tmpId && x148_28_playerTriggerProc) { x148_28_playerTriggerProc = false; if (x148_29_didPhazonDamage) { - mgr.Player()->DecrementPhazon(); + mgr.Player()->DecrementEnvironmentDamage(); x148_29_didPhazonDamage = false; } diff --git a/tools/metaforce_renames.py b/tools/metaforce_renames.py index 38255b0a..ed758465 100644 --- a/tools/metaforce_renames.py +++ b/tools/metaforce_renames.py @@ -32,6 +32,7 @@ _LITERAL_REPLACEMENTS = [ ("char16_t", "wchar_t"), ("std::min(", "rstl::min_val("), ("std::max(", "rstl::max_val("), + ("constexpr ", "const "), ("DEFINE_ENTITY", ""), ("visitor.Visit(this)", "visitor.Visit(*this)"), @@ -94,11 +95,19 @@ _LITERAL_REPLACEMENTS = [ ("EProjectileAttrib::", "kPA_"), ("ERumbleFxId::", "kRFX_"), ("ERumblePriority::", "kRP_"), + ("EWhichModel::", "kWM_"), + ("EArmState::", "kAS_"), + ("EGameState::", "kGS_"), + ("EScanState::", "kSS_"), + ("EWeaponType::", "kWT_"), + ("EFluidState::", "kFS_"), + ("EPhazonType::", "kPT_"), # CActor ("x34_transform.origin", "GetTranslation()"), ("x34_transform", "GetTransform()"), ("xc4_fluidId", "InFluidId()"), + ("x90_actorLights.get()", "GetActorLights()"), # CPhysicsActor ("x138_velocity", "GetVelocityWR()"), @@ -132,6 +141,8 @@ _RE_REPLACEMENTS = [ (re.compile(r"\.([xyz])\(\)"), lambda m: f".Get{m.group(1).upper()}()"), # lhs.dot(rhs) -> CVector3f::Dot(lhs, rhs) (re.compile(r"([A-z0-9]+)\.dot\(([A-z0-9]+)\)([,;])"), r"CVector3f::Dot(\1, \2)\3"), + # std::make_unique -> rs_new T + (re.compile(r"std::make_unique<([A-z0-9]+)>"), r"rs_new \1"), ] diff --git a/tools/project.py b/tools/project.py index 1d9c79be..0b200475 100644 --- a/tools/project.py +++ b/tools/project.py @@ -17,7 +17,7 @@ import os import platform import sys from pathlib import Path -from typing import IO, Any, Dict, Iterable, List, Optional, Set, Tuple, cast +from typing import IO, Any, Dict, Iterable, List, Optional, Set, Tuple, Union, cast from . import ninja_syntax from .ninja_syntax import serialize_path @@ -81,6 +81,18 @@ class Object: set_default("shift_jis", config.shift_jis) set_default("src_dir", config.src_dir) + # Validate progress categories + def check_category(category: str): + if not any(category == c.id for c in config.progress_categories): + sys.exit(f"Progress category '{category}' missing from config.progress_categories") + + progress_category = obj.options["progress_category"] + if isinstance(progress_category, list): + for category in progress_category: + check_category(category) + elif progress_category is not None: + check_category(progress_category) + # Resolve paths build_dir = config.out_path() obj.src_path = Path(obj.options["src_dir"]) / obj.options["source"] @@ -160,13 +172,16 @@ class ProjectConfig: ) # Progress output, progress.json and report.json config - self.progress = True # Enable progress output + self.progress = True # Enable CLI progress output self.progress_all: bool = True # Include combined "all" category self.progress_modules: bool = True # Include combined "modules" category self.progress_each_module: bool = ( False # Include individual modules, disable for large numbers of modules ) self.progress_categories: List[ProgressCategory] = [] # Additional categories + self.print_progress_categories: Union[bool, List[str]] = ( + True # Print additional progress categories in the CLI progress output + ) # Progress fancy printing self.progress_use_fancy: bool = False @@ -1687,7 +1702,11 @@ def calculate_progress(config: ProjectConfig) -> None: print_category("All", report_data["measures"]) for category in report_data["categories"]: - print_category(category["name"], category["measures"]) + if config.print_progress_categories is True or ( + isinstance(config.print_progress_categories, list) + and category["id"] in config.print_progress_categories + ): + print_category(category["name"], category["measures"]) if config.progress_use_fancy: measures = report_data["measures"]