diff --git a/asm/MetroidPrime/CEnvFxManager.s b/asm/MetroidPrime/CEnvFxManager.s index 222bfbad..34e66fb8 100644 --- a/asm/MetroidPrime/CEnvFxManager.s +++ b/asm/MetroidPrime/CEnvFxManager.s @@ -167,8 +167,8 @@ lbl_8020FF34: /* 8020FF54 0020CEB4 38 21 00 30 */ addi r1, r1, 0x30 /* 8020FF58 0020CEB8 4E 80 00 20 */ blr -.global sub_8020ff5c -sub_8020ff5c: +.global SetFxDensity__13CEnvFxManagerFv +SetFxDensity__13CEnvFxManagerFv: /* 8020FF5C 0020CEBC 94 21 FF F0 */ stwu r1, -0x10(r1) /* 8020FF60 0020CEC0 6C 84 80 00 */ xoris r4, r4, 0x8000 /* 8020FF64 0020CEC4 3C 00 43 30 */ lis r0, 0x4330 @@ -4583,4 +4583,3 @@ lbl_803D2818: .asciz "TXTR_UnderwaterFlake" .balign 4 .4byte 0 - diff --git a/asm/MetroidPrime/Cameras/CCameraManager.s b/asm/MetroidPrime/Cameras/CCameraManager.s index 15d06df4..3434e80a 100644 --- a/asm/MetroidPrime/Cameras/CCameraManager.s +++ b/asm/MetroidPrime/Cameras/CCameraManager.s @@ -2754,8 +2754,8 @@ Update__14CCameraManagerFfR13CStateManager: /* 8000B5C4 00008524 38 21 00 20 */ addi r1, r1, 0x20 /* 8000B5C8 00008528 4E 80 00 20 */ blr -.global sub_8000b5cc -sub_8000b5cc: +.global SetFogDensity__14CCameraManagerFfFf +SetFogDensity__14CCameraManagerFfFf: /* 8000B5CC 0000852C D0 23 00 9C */ stfs f1, 0x9c(r3) /* 8000B5D0 00008530 C0 23 00 9C */ lfs f1, 0x9c(r3) /* 8000B5D4 00008534 C0 03 00 94 */ lfs f0, 0x94(r3) diff --git a/asm/MetroidPrime/ScriptLoader.s b/asm/MetroidPrime/ScriptLoader.s index 72cfcce6..1cd3bf76 100644 --- a/asm/MetroidPrime/ScriptLoader.s +++ b/asm/MetroidPrime/ScriptLoader.s @@ -3964,7 +3964,7 @@ lbl_800C8844: /* 800C89D8 000C5938 C8 01 00 C0 */ lfd f0, 0xc0(r1) /* 800C89DC 000C593C 93 61 00 28 */ stw r27, 0x28(r1) /* 800C89E0 000C5940 EC 60 18 28 */ fsubs f3, f0, f3 -/* 800C89E4 000C5944 48 08 A1 DD */ bl "__ct__22CScriptSpecialFunctionF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fQ222CScriptSpecialFunction16ESpecialFunctionRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>ffffRC9CVector3fRC6CColorbRC11CDamageInfoUiUiUiUsUsUs" +/* 800C89E4 000C5944 48 08 A1 DD */ bl "__ct__22CScriptSpecialFunctionF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fQ222CScriptSpecialFunction16ESpecialFunctionRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>ffffRC9CVector3fRC6CColorbRC11CDamageInfollQ212CPlayerState9EItemTypesss" /* 800C89E8 000C5948 7C 7C 1B 78 */ mr r28, r3 lbl_800C89EC: /* 800C89EC 000C594C 7F 20 07 75 */ extsb. r0, r25 @@ -5569,7 +5569,7 @@ lbl_800CA054: /* 800CA1A8 000C7108 C8 01 00 80 */ lfd f0, 0x80(r1) /* 800CA1AC 000C710C 93 61 00 28 */ stw r27, 0x28(r1) /* 800CA1B0 000C7110 EC 40 10 28 */ fsubs f2, f0, f2 -/* 800CA1B4 000C7114 48 08 8A 0D */ bl "__ct__22CScriptSpecialFunctionF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fQ222CScriptSpecialFunction16ESpecialFunctionRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>ffffRC9CVector3fRC6CColorbRC11CDamageInfoUiUiUiUsUsUs" +/* 800CA1B4 000C7114 48 08 8A 0D */ bl "__ct__22CScriptSpecialFunctionF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fQ222CScriptSpecialFunction16ESpecialFunctionRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>ffffRC9CVector3fRC6CColorbRC11CDamageInfollQ212CPlayerState9EItemTypesss" /* 800CA1B8 000C7118 7C 7D 1B 78 */ mr r29, r3 lbl_800CA1BC: /* 800CA1BC 000C711C 7F 40 07 75 */ extsb. r0, r26 @@ -5919,7 +5919,7 @@ lbl_800CA580: /* 800CA6C0 000C7620 93 41 00 20 */ stw r26, 0x20(r1) /* 800CA6C4 000C7624 93 41 00 24 */ stw r26, 0x24(r1) /* 800CA6C8 000C7628 93 41 00 28 */ stw r26, 0x28(r1) -/* 800CA6CC 000C762C 48 08 84 F5 */ bl "__ct__22CScriptSpecialFunctionF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fQ222CScriptSpecialFunction16ESpecialFunctionRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>ffffRC9CVector3fRC6CColorbRC11CDamageInfoUiUiUiUsUsUs" +/* 800CA6CC 000C762C 48 08 84 F5 */ bl "__ct__22CScriptSpecialFunctionF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fQ222CScriptSpecialFunction16ESpecialFunctionRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>ffffRC9CVector3fRC6CColorbRC11CDamageInfollQ212CPlayerState9EItemTypesss" /* 800CA6D0 000C7630 7C 7B 1B 78 */ mr r27, r3 lbl_800CA6D4: /* 800CA6D4 000C7634 7F C0 07 75 */ extsb. r0, r30 @@ -15309,7 +15309,7 @@ lbl_800D2E70: /* 800D3020 000CFF80 93 81 00 20 */ stw r28, 0x20(r1) /* 800D3024 000CFF84 93 81 00 24 */ stw r28, 0x24(r1) /* 800D3028 000CFF88 93 81 00 28 */ stw r28, 0x28(r1) -/* 800D302C 000CFF8C 48 07 FB 95 */ bl "__ct__22CScriptSpecialFunctionF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fQ222CScriptSpecialFunction16ESpecialFunctionRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>ffffRC9CVector3fRC6CColorbRC11CDamageInfoUiUiUiUsUsUs" +/* 800D302C 000CFF8C 48 07 FB 95 */ bl "__ct__22CScriptSpecialFunctionF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fQ222CScriptSpecialFunction16ESpecialFunctionRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>ffffRC9CVector3fRC6CColorbRC11CDamageInfollQ212CPlayerState9EItemTypesss" /* 800D3030 000CFF90 7C 7F 1B 78 */ mr r31, r3 lbl_800D3034: /* 800D3034 000CFF94 7F 40 07 75 */ extsb. r0, r26 @@ -15473,7 +15473,7 @@ lbl_800D31AC: /* 800D328C 000D01EC 93 21 00 20 */ stw r25, 0x20(r1) /* 800D3290 000D01F0 93 01 00 24 */ stw r24, 0x24(r1) /* 800D3294 000D01F4 92 E1 00 28 */ stw r23, 0x28(r1) -/* 800D3298 000D01F8 48 07 F9 29 */ bl "__ct__22CScriptSpecialFunctionF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fQ222CScriptSpecialFunction16ESpecialFunctionRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>ffffRC9CVector3fRC6CColorbRC11CDamageInfoUiUiUiUsUsUs" +/* 800D3298 000D01F8 48 07 F9 29 */ bl "__ct__22CScriptSpecialFunctionF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fQ222CScriptSpecialFunction16ESpecialFunctionRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>ffffRC9CVector3fRC6CColorbRC11CDamageInfollQ212CPlayerState9EItemTypesss" /* 800D329C 000D01FC 7C 7A 1B 78 */ mr r26, r3 lbl_800D32A0: /* 800D32A0 000D0200 38 61 00 44 */ addi r3, r1, 0x44 diff --git a/asm/MetroidPrime/ScriptObjects/CScriptAreaAttributes.s b/asm/MetroidPrime/ScriptObjects/CScriptAreaAttributes.s index ff91b980..dac04b4a 100644 --- a/asm/MetroidPrime/ScriptObjects/CScriptAreaAttributes.s +++ b/asm/MetroidPrime/ScriptObjects/CScriptAreaAttributes.s @@ -100,7 +100,7 @@ lbl_801BD53C: /* 801BD560 001BA4C0 80 7F 08 80 */ lwz r3, 0x880(r31) /* 801BD564 001BA4C4 38 80 01 F4 */ li r4, 0x1f4 /* 801BD568 001BA4C8 C0 3D 00 3C */ lfs f1, 0x3c(r29) -/* 801BD56C 001BA4CC 48 05 29 F1 */ bl sub_8020ff5c +/* 801BD56C 001BA4CC 48 05 29 F1 */ bl SetFxDensity__13CEnvFxManagerFv /* 801BD570 001BA4D0 48 00 00 3C */ b lbl_801BD5AC lbl_801BD574: /* 801BD574 001BA4D4 80 9F 08 50 */ lwz r4, 0x850(r31) @@ -189,4 +189,3 @@ lbl_803D19F0: # ROM: 0x3CE9F0 .4byte 0 .4byte 0 - diff --git a/asm/MetroidPrime/ScriptObjects/CScriptSpecialFunction.s b/asm/MetroidPrime/ScriptObjects/CScriptSpecialFunction.s index 91f8d7fc..0b28a6e9 100644 --- a/asm/MetroidPrime/ScriptObjects/CScriptSpecialFunction.s +++ b/asm/MetroidPrime/ScriptObjects/CScriptSpecialFunction.s @@ -15,7 +15,7 @@ lbl_803E2B68: .4byte AcceptScriptMsg__22CScriptSpecialFunctionF20EScriptObjectMessage9TUniqueIdR13CStateManager .4byte SetActive__6CActorFb .4byte PreRender__22CScriptSpecialFunctionFR13CStateManagerRC14CFrustumPlanes - .4byte AddToRenderer__22CScriptSpecialFunctionCFRC14CFrustumPlanesRC13CStateManager + .4byte AddToRenderer__22CScriptSpecialFunctionFRC14CFrustumPlanesR13CStateManager .4byte Render__22CScriptSpecialFunctionCFRC13CStateManager .4byte CanRenderUnsorted__6CActorCFRC13CStateManager .4byte CalculateRenderBounds__6CActorFv @@ -442,8 +442,8 @@ lbl_8014F530: /* 8014F538 0014C498 38 21 00 10 */ addi r1, r1, 0x10 /* 8014F53C 0014C49C 4E 80 00 20 */ blr -.global sub_8014f540 -sub_8014f540: +.global ThinkActorScale__22CScriptSpecialFunctionFfR13CStateManager +ThinkActorScale__22CScriptSpecialFunctionFfR13CStateManager: /* 8014F540 0014C4A0 94 21 FF 80 */ stwu r1, -0x80(r1) /* 8014F544 0014C4A4 7C 08 02 A6 */ mflr r0 /* 8014F548 0014C4A8 90 01 00 84 */ stw r0, 0x84(r1) @@ -3044,7 +3044,6 @@ lbl_80151A14: /* 80151A38 0014E998 7C 03 00 2E */ lwzx r0, r3, r0 /* 80151A3C 0014E99C 7C 09 03 A6 */ mtctr r0 /* 80151A40 0014E9A0 4E 80 04 20 */ bctr -.global lbl_80151A44 lbl_80151A44: /* 80151A44 0014E9A4 2C 1C 00 13 */ cmpwi r28, 0x13 /* 80151A48 0014E9A8 40 82 0E 58 */ bne lbl_801528A0 @@ -3054,7 +3053,6 @@ lbl_80151A44: /* 80151A58 0014E9B8 C0 62 9D A4 */ lfs f3, lbl_805ABAC4@sda21(r2) /* 80151A5C 0014E9BC 4B EC 16 11 */ bl SetHudDisable__7CPlayerFfff /* 80151A60 0014E9C0 48 00 0E 40 */ b lbl_801528A0 -.global lbl_80151A64 lbl_80151A64: /* 80151A64 0014E9C4 2C 1C 00 13 */ cmpwi r28, 0x13 /* 80151A68 0014E9C8 40 82 0E 38 */ bne lbl_801528A0 @@ -3066,7 +3064,6 @@ lbl_80151A64: /* 80151A80 0014E9E0 7F C3 F3 78 */ mr r3, r30 /* 80151A84 0014E9E4 4B EF 35 F9 */ bl ResetEscapeSequenceTimer__13CStateManagerFf /* 80151A88 0014E9E8 48 00 0E 18 */ b lbl_801528A0 -.global lbl_80151A8C lbl_80151A8C: /* 80151A8C 0014E9EC 2C 1C 00 0F */ cmpwi r28, 0xf /* 80151A90 0014E9F0 41 82 00 48 */ beq lbl_80151AD8 @@ -3100,7 +3097,6 @@ lbl_80151AEC: /* 80151AF0 0014EA50 38 9F 01 78 */ addi r4, r31, 0x178 /* 80151AF4 0014EA54 4B FF D8 B1 */ bl sub_8014f3a4 /* 80151AF8 0014EA58 48 00 0D A8 */ b lbl_801528A0 -.global lbl_80151AFC lbl_80151AFC: /* 80151AFC 0014EA5C 2C 1C 00 07 */ cmpwi r28, 7 /* 80151B00 0014EA60 40 82 00 64 */ bne lbl_80151B64 @@ -3151,7 +3147,6 @@ lbl_80151B8C: /* 80151B9C 0014EAFC EC 01 00 32 */ fmuls f0, f1, f0 /* 80151BA0 0014EB00 D0 1F 01 6C */ stfs f0, 0x16c(r31) /* 80151BA4 0014EB04 48 00 0C FC */ b lbl_801528A0 -.global lbl_80151BA8 lbl_80151BA8: /* 80151BA8 0014EB08 2C 1C 00 13 */ cmpwi r28, 0x13 /* 80151BAC 0014EB0C 40 82 0C F4 */ bne lbl_801528A0 @@ -3169,7 +3164,6 @@ lbl_80151BA8: /* 80151BDC 0014EB3C 38 80 00 01 */ li r4, 1 /* 80151BE0 0014EB40 4B EF 2C 81 */ bl DeferStateTransition__13CStateManagerF23EStateManagerTransition /* 80151BE4 0014EB44 48 00 0C BC */ b lbl_801528A0 -.global lbl_80151BE8 lbl_80151BE8: /* 80151BE8 0014EB48 2C 1C 00 13 */ cmpwi r28, 0x13 /* 80151BEC 0014EB4C 40 82 0C B4 */ bne lbl_801528A0 @@ -3183,7 +3177,6 @@ lbl_80151BE8: /* 80151C0C 0014EB6C 38 80 00 04 */ li r4, 4 /* 80151C10 0014EB70 4B F4 00 F1 */ bl ResetAndIncrPickUp__12CPlayerStateFQ212CPlayerState9EItemTypei /* 80151C14 0014EB74 48 00 0C 8C */ b lbl_801528A0 -.global lbl_80151C18 lbl_80151C18: /* 80151C18 0014EB78 2C 1C 00 13 */ cmpwi r28, 0x13 /* 80151C1C 0014EB7C 40 82 0C 84 */ bne lbl_801528A0 @@ -3197,7 +3190,6 @@ lbl_80151C18: /* 80151C3C 0014EB9C 38 80 00 07 */ li r4, 7 /* 80151C40 0014EBA0 4B F4 00 C1 */ bl ResetAndIncrPickUp__12CPlayerStateFQ212CPlayerState9EItemTypei /* 80151C44 0014EBA4 48 00 0C 5C */ b lbl_801528A0 -.global lbl_80151C48 lbl_80151C48: /* 80151C48 0014EBA8 2C 1C 00 13 */ cmpwi r28, 0x13 /* 80151C4C 0014EBAC 40 82 0C 54 */ bne lbl_801528A0 @@ -3233,7 +3225,6 @@ lbl_80151CA8: /* 80151CC0 0014EC20 50 60 3E 30 */ rlwimi r0, r3, 7, 0x18, 0x18 /* 80151CC4 0014EC24 98 1F 01 E5 */ stb r0, 0x1e5(r31) /* 80151CC8 0014EC28 48 00 0B D8 */ b lbl_801528A0 -.global lbl_80151CCC lbl_80151CCC: /* 80151CCC 0014EC2C 80 1F 01 A8 */ lwz r0, 0x1a8(r31) /* 80151CD0 0014EC30 2C 00 00 03 */ cmpwi r0, 3 @@ -3474,7 +3465,6 @@ lbl_80151FE4: /* 80152028 0014EF88 D0 1F 01 B4 */ stfs f0, 0x1b4(r31) /* 8015202C 0014EF8C 48 1C 28 CD */ bl Normalize__9CVector3fFv /* 80152030 0014EF90 48 00 08 70 */ b lbl_801528A0 -.global lbl_80152034 lbl_80152034: /* 80152034 0014EF94 2C 1C 00 13 */ cmpwi r28, 0x13 /* 80152038 0014EF98 40 82 08 68 */ bne lbl_801528A0 @@ -3522,7 +3512,6 @@ lbl_80152034: /* 801520E0 0014F040 B0 01 00 24 */ sth r0, 0x24(r1) /* 801520E4 0014F044 4B EF 6B C9 */ bl ApplyDamageToWorld__13CStateManagerF9TUniqueIdRC6CActorRC9CVector3fRC11CDamageInfoRC15CMaterialFilter /* 801520E8 0014F048 48 00 07 B8 */ b lbl_801528A0 -.global lbl_801520EC lbl_801520EC: /* 801520EC 0014F04C 2C 1C 00 07 */ cmpwi r28, 7 /* 801520F0 0014F050 40 82 00 34 */ bne lbl_80152124 @@ -3549,7 +3538,6 @@ lbl_80152124: /* 80152140 0014F0A0 38 A0 00 00 */ li r5, 0 /* 80152144 0014F0A4 4B EF 1E 01 */ bl SetBossParams__13CStateManagerF9TUniqueIdfUi /* 80152148 0014F0A8 48 00 07 58 */ b lbl_801528A0 -.global lbl_8015214C lbl_8015214C: /* 8015214C 0014F0AC 2C 1C 00 13 */ cmpwi r28, 0x13 /* 80152150 0014F0B0 40 82 07 50 */ bne lbl_801528A0 @@ -3586,7 +3574,6 @@ lbl_801521B0: /* 801521B8 0014F118 50 60 36 72 */ rlwimi r0, r3, 6, 0x19, 0x19 /* 801521BC 0014F11C 98 1E 0F 94 */ stb r0, 0xf94(r30) /* 801521C0 0014F120 48 00 06 E0 */ b lbl_801528A0 -.global lbl_801521C4 lbl_801521C4: /* 801521C4 0014F124 2C 1C 00 07 */ cmpwi r28, 7 /* 801521C8 0014F128 40 82 00 2C */ bne lbl_801521F4 @@ -3619,7 +3606,6 @@ lbl_801521F4: /* 80152230 0014F190 90 01 00 B0 */ stw r0, 0xb0(r1) /* 80152234 0014F194 48 08 30 DD */ bl SetCinematicState__14CSystemOptionsFUi9TEditorIdb /* 80152238 0014F198 48 00 06 68 */ b lbl_801528A0 -.global lbl_8015223C lbl_8015223C: /* 8015223C 0014F19C 2C 1C 00 06 */ cmpwi r28, 6 /* 80152240 0014F1A0 41 82 00 E4 */ beq lbl_80152324 @@ -3683,7 +3669,6 @@ lbl_801522F0: /* 80152318 0014F278 90 E1 00 3C */ stw r7, 0x3c(r1) /* 8015231C 0014F27C 90 01 00 40 */ stw r0, 0x40(r1) /* 80152320 0014F280 48 0E 1F A1 */ bl SetLayerActive__16CWorldLayerStateFiib -.global lbl_80152324 lbl_80152324: /* 80152324 0014F284 2C 1C 00 13 */ cmpwi r28, 0x13 /* 80152328 0014F288 40 82 05 78 */ bne lbl_801528A0 @@ -3693,9 +3678,8 @@ lbl_80152324: /* 80152338 0014F298 C0 3F 00 FC */ lfs f1, 0xfc(r31) /* 8015233C 0014F29C D8 01 01 50 */ stfd f0, 0x150(r1) /* 80152340 0014F2A0 80 81 01 54 */ lwz r4, 0x154(r1) -/* 80152344 0014F2A4 48 0B DC 19 */ bl sub_8020ff5c +/* 80152344 0014F2A4 48 0B DC 19 */ bl SetFxDensity__13CEnvFxManagerFv /* 80152348 0014F2A8 48 00 05 58 */ b lbl_801528A0 -.global lbl_8015234C lbl_8015234C: /* 8015234C 0014F2AC 2C 1C 00 13 */ cmpwi r28, 0x13 /* 80152350 0014F2B0 40 82 05 50 */ bne lbl_801528A0 @@ -3757,7 +3741,6 @@ lbl_80152414: /* 80152428 0014F388 38 E0 00 01 */ li r7, 1 /* 8015242C 0014F38C 48 0D BD 1D */ bl Rumble__14CRumbleManagerFR13CStateManagerRC9CVector3f11ERumbleFxIdf15ERumblePriority /* 80152430 0014F390 48 00 04 70 */ b lbl_801528A0 -.global lbl_80152434 lbl_80152434: /* 80152434 0014F394 2C 1C 00 13 */ cmpwi r28, 0x13 /* 80152438 0014F398 40 82 04 68 */ bne lbl_801528A0 @@ -3773,7 +3756,6 @@ lbl_80152434: /* 80152460 0014F3C0 38 C0 FF FF */ li r6, -1 /* 80152464 0014F3C4 4B EF EC 5D */ bl SendScriptMsgs__7CEntityF18EScriptObjectStateR13CStateManager20EScriptObjectMessage /* 80152468 0014F3C8 48 00 04 38 */ b lbl_801528A0 -.global lbl_8015246C lbl_8015246C: /* 8015246C 0014F3CC 2C 1C 00 13 */ cmpwi r28, 0x13 /* 80152470 0014F3D0 40 82 04 30 */ bne lbl_801528A0 @@ -3788,7 +3770,6 @@ lbl_8015246C: /* 80152494 0014F3F4 38 C0 FF FF */ li r6, -1 /* 80152498 0014F3F8 4B EF EC 29 */ bl SendScriptMsgs__7CEntityF18EScriptObjectStateR13CStateManager20EScriptObjectMessage /* 8015249C 0014F3FC 48 00 04 04 */ b lbl_801528A0 -.global lbl_801524A0 lbl_801524A0: /* 801524A0 0014F400 2C 1C 00 22 */ cmpwi r28, 0x22 /* 801524A4 0014F404 41 82 00 0C */ beq lbl_801524B0 @@ -3808,7 +3789,6 @@ lbl_801524B0: /* 801524D8 0014F438 50 60 0F BC */ rlwimi r0, r3, 1, 0x1e, 0x1e /* 801524DC 0014F43C 98 1E 0F 94 */ stb r0, 0xf94(r30) /* 801524E0 0014F440 48 00 03 C0 */ b lbl_801528A0 -.global lbl_801524E4 lbl_801524E4: /* 801524E4 0014F444 2C 1C 00 13 */ cmpwi r28, 0x13 /* 801524E8 0014F448 40 82 03 B8 */ bne lbl_801528A0 @@ -3830,7 +3810,6 @@ lbl_80152518: /* 80152524 0014F484 80 63 04 90 */ lwz r3, 0x490(r3) /* 80152528 0014F488 4B EE D7 1D */ bl DropBomb__10CPlayerGunFQ210CPlayerGun8EBWeaponR13CStateManager /* 8015252C 0014F48C 48 00 03 74 */ b lbl_801528A0 -.global lbl_80152530 lbl_80152530: /* 80152530 0014F490 80 6D A0 80 */ lwz r3, gpGameState@sda21(r13) /* 80152534 0014F494 2C 1C 00 13 */ cmpwi r28, 0x13 @@ -3851,7 +3830,6 @@ lbl_80152560: /* 80152568 0014F4C8 38 9F 00 EC */ addi r4, r31, 0xec /* 8015256C 0014F4CC 48 11 52 BD */ bl DelayHint__12CHintOptionsFPCc /* 80152570 0014F4D0 48 00 03 30 */ b lbl_801528A0 -.global lbl_80152574 lbl_80152574: /* 80152574 0014F4D4 2C 1C 00 07 */ cmpwi r28, 7 /* 80152578 0014F4D8 40 82 01 18 */ bne lbl_80152690 @@ -4002,7 +3980,6 @@ lbl_80152780: /* 8015278C 0014F6EC 50 60 2E B4 */ rlwimi r0, r3, 5, 0x1a, 0x1a /* 80152790 0014F6F0 98 1F 01 E5 */ stb r0, 0x1e5(r31) /* 80152794 0014F6F4 48 00 01 0C */ b lbl_801528A0 -.global lbl_80152798 lbl_80152798: /* 80152798 0014F6F8 2C 1C 00 13 */ cmpwi r28, 0x13 /* 8015279C 0014F6FC 41 82 00 0C */ beq lbl_801527A8 @@ -4020,7 +3997,6 @@ lbl_801527A8: /* 801527C8 0014F728 38 C0 FF FF */ li r6, -1 /* 801527CC 0014F72C 4B EF E8 F5 */ bl SendScriptMsgs__7CEntityF18EScriptObjectStateR13CStateManager20EScriptObjectMessage /* 801527D0 0014F730 48 00 00 D0 */ b lbl_801528A0 -.global lbl_801527D4 lbl_801527D4: /* 801527D4 0014F734 2C 1C 00 07 */ cmpwi r28, 7 /* 801527D8 0014F738 40 82 00 1C */ bne lbl_801527F4 @@ -4039,23 +4015,21 @@ lbl_801527F4: /* 80152808 0014F768 38 A0 00 33 */ li r5, 0x33 /* 8015280C 0014F76C 4B F0 16 C9 */ bl RemoveMaterial__6CActorF14EMaterialTypes14EMaterialTypesR13CStateManager /* 80152810 0014F770 48 00 00 90 */ b lbl_801528A0 -.global lbl_80152814 lbl_80152814: /* 80152814 0014F774 2C 1C 00 07 */ cmpwi r28, 7 /* 80152818 0014F778 C0 5F 01 00 */ lfs f2, 0x100(r31) /* 8015281C 0014F77C 40 82 00 14 */ bne lbl_80152830 /* 80152820 0014F780 80 7E 08 70 */ lwz r3, 0x870(r30) /* 80152824 0014F784 C0 3F 00 FC */ lfs f1, 0xfc(r31) -/* 80152828 0014F788 4B EB 8D A5 */ bl sub_8000b5cc +/* 80152828 0014F788 4B EB 8D A5 */ bl SetFogDensity__14CCameraManagerFfFf /* 8015282C 0014F78C 48 00 00 74 */ b lbl_801528A0 lbl_80152830: /* 80152830 0014F790 2C 1C 00 05 */ cmpwi r28, 5 /* 80152834 0014F794 40 82 00 6C */ bne lbl_801528A0 /* 80152838 0014F798 80 7E 08 70 */ lwz r3, 0x870(r30) /* 8015283C 0014F79C C0 22 9D B4 */ lfs f1, lbl_805ABAD4@sda21(r2) -/* 80152840 0014F7A0 4B EB 8D 8D */ bl sub_8000b5cc +/* 80152840 0014F7A0 4B EB 8D 8D */ bl SetFogDensity__14CCameraManagerFfFf /* 80152844 0014F7A4 48 00 00 5C */ b lbl_801528A0 -.global lbl_80152848 lbl_80152848: /* 80152848 0014F7A8 2C 1C 00 13 */ cmpwi r28, 0x13 /* 8015284C 0014F7AC 40 82 00 54 */ bne lbl_801528A0 @@ -4063,7 +4037,6 @@ lbl_80152848: /* 80152854 0014F7B4 38 80 00 03 */ li r4, 3 /* 80152858 0014F7B8 4B EF 20 09 */ bl DeferStateTransition__13CStateManagerF23EStateManagerTransition /* 8015285C 0014F7BC 48 00 00 44 */ b lbl_801528A0 -.global lbl_80152860 lbl_80152860: /* 80152860 0014F7C0 2C 1C 00 13 */ cmpwi r28, 0x13 /* 80152864 0014F7C4 40 82 00 3C */ bne lbl_801528A0 @@ -4081,7 +4054,6 @@ lbl_80152860: /* 80152894 0014F7F4 38 80 00 09 */ li r4, 9 /* 80152898 0014F7F8 38 C0 FF FF */ li r6, -1 /* 8015289C 0014F7FC 4B EF E8 25 */ bl SendScriptMsgs__7CEntityF18EScriptObjectStateR13CStateManager20EScriptObjectMessage -.global lbl_801528A0 lbl_801528A0: /* 801528A0 0014F800 E3 E1 01 B8 */ psq_l f31, 440(r1), 0, qr0 /* 801528A4 0014F804 CB E1 01 B0 */ lfd f31, 0x1b0(r1) @@ -4184,8 +4156,8 @@ lbl_801529F4: /* 80152A04 0014F964 38 21 00 50 */ addi r1, r1, 0x50 /* 80152A08 0014F968 4E 80 00 20 */ blr -.global AddToRenderer__22CScriptSpecialFunctionCFRC14CFrustumPlanesRC13CStateManager -AddToRenderer__22CScriptSpecialFunctionCFRC14CFrustumPlanesRC13CStateManager: +.global AddToRenderer__22CScriptSpecialFunctionFRC14CFrustumPlanesR13CStateManager +AddToRenderer__22CScriptSpecialFunctionFRC14CFrustumPlanesR13CStateManager: /* 80152A0C 0014F96C 94 21 FF F0 */ stwu r1, -0x10(r1) /* 80152A10 0014F970 7C 08 02 A6 */ mflr r0 /* 80152A14 0014F974 90 01 00 14 */ stw r0, 0x14(r1) @@ -4227,33 +4199,26 @@ Think__22CScriptSpecialFunctionFfR13CStateManager: /* 80152A94 0014F9F4 7C 05 00 2E */ lwzx r0, r5, r0 /* 80152A98 0014F9F8 7C 09 03 A6 */ mtctr r0 /* 80152A9C 0014F9FC 4E 80 04 20 */ bctr -.global lbl_80152AA0 lbl_80152AA0: /* 80152AA0 0014FA00 4B FF E4 D1 */ bl ThinkPlayerFollowLocator__22CScriptSpecialFunctionFfR13CStateManager /* 80152AA4 0014FA04 48 00 01 04 */ b lbl_80152BA8 -.global lbl_80152AA8 lbl_80152AA8: /* 80152AA8 0014FA08 38 A0 00 00 */ li r5, 0 /* 80152AAC 0014FA0C 4B FF D7 E1 */ bl ThinkSpinnerController__22CScriptSpecialFunctionFfR13CStateManagerQ222CScriptSpecialFunction22ESpinnerControllerMode /* 80152AB0 0014FA10 48 00 00 F8 */ b lbl_80152BA8 -.global lbl_80152AB4 lbl_80152AB4: /* 80152AB4 0014FA14 38 A0 00 01 */ li r5, 1 /* 80152AB8 0014FA18 4B FF D7 D5 */ bl ThinkSpinnerController__22CScriptSpecialFunctionFfR13CStateManagerQ222CScriptSpecialFunction22ESpinnerControllerMode /* 80152ABC 0014FA1C 48 00 00 EC */ b lbl_80152BA8 -.global lbl_80152AC0 lbl_80152AC0: /* 80152AC0 0014FA20 4B FF D5 99 */ bl ThinkObjectFollowLocator__22CScriptSpecialFunctionFfR13CStateManager /* 80152AC4 0014FA24 48 00 00 E4 */ b lbl_80152BA8 -.global lbl_80152AC8 lbl_80152AC8: /* 80152AC8 0014FA28 4B FF D3 CD */ bl ThinkObjectFollowObject__22CScriptSpecialFunctionFfR13CStateManager /* 80152ACC 0014FA2C 48 00 00 DC */ b lbl_80152BA8 -.global lbl_80152AD0 lbl_80152AD0: /* 80152AD0 0014FA30 4B FF CE F1 */ bl ThinkChaffTarget__22CScriptSpecialFunctionFfR13CStateManager /* 80152AD4 0014FA34 48 00 00 D4 */ b lbl_80152BA8 -.global lbl_80152AD8 lbl_80152AD8: /* 80152AD8 0014FA38 88 9E 01 E4 */ lbz r4, 0x1e4(r30) /* 80152ADC 0014FA3C 54 80 EF FF */ rlwinm. r0, r4, 0x1d, 0x1f, 0x1f @@ -4278,31 +4243,24 @@ lbl_80152B00: /* 80152B24 0014FA84 38 C0 FF FF */ li r6, -1 /* 80152B28 0014FA88 4B EF E5 99 */ bl SendScriptMsgs__7CEntityF18EScriptObjectStateR13CStateManager20EScriptObjectMessage /* 80152B2C 0014FA8C 48 00 00 7C */ b lbl_80152BA8 -.global lbl_80152B30 lbl_80152B30: /* 80152B30 0014FA90 4B FF EB 7D */ bl ThinkSaveStation__22CScriptSpecialFunctionFfR13CStateManager /* 80152B34 0014FA94 48 00 00 74 */ b lbl_80152BA8 -.global lbl_80152B38 lbl_80152B38: /* 80152B38 0014FA98 4B FF E5 E5 */ bl ThinkIntroBossRingController__22CScriptSpecialFunctionFfR13CStateManager /* 80152B3C 0014FA9C 48 00 00 6C */ b lbl_80152BA8 -.global lbl_80152B40 lbl_80152B40: /* 80152B40 0014FAA0 4B FF CD F9 */ bl ThinkRainSimulator__22CScriptSpecialFunctionFfR13CStateManager /* 80152B44 0014FAA4 48 00 00 64 */ b lbl_80152BA8 -.global lbl_80152B48 lbl_80152B48: /* 80152B48 0014FAA8 4B FF CB F1 */ bl ThinkAreaDamage__22CScriptSpecialFunctionFfR13CStateManager /* 80152B4C 0014FAAC 48 00 00 5C */ b lbl_80152BA8 -.global lbl_80152B50 lbl_80152B50: -/* 80152B50 0014FAB0 4B FF C9 F1 */ bl sub_8014f540 +/* 80152B50 0014FAB0 4B FF C9 F1 */ bl ThinkActorScale__22CScriptSpecialFunctionFfR13CStateManager /* 80152B54 0014FAB4 48 00 00 54 */ b lbl_80152BA8 -.global lbl_80152B58 lbl_80152B58: /* 80152B58 0014FAB8 4B FF C9 65 */ bl ThinkPlayerInArea__22CScriptSpecialFunctionFfR13CStateManager /* 80152B5C 0014FABC 48 00 00 4C */ b lbl_80152BA8 -.global lbl_80152B60 lbl_80152B60: /* 80152B60 0014FAC0 88 1E 01 F0 */ lbz r0, 0x1f0(r30) /* 80152B64 0014FAC4 28 00 00 00 */ cmplwi r0, 0 @@ -4322,7 +4280,6 @@ lbl_80152B60: /* 80152B9C 0014FAFC 38 60 00 00 */ li r3, 0 /* 80152BA0 0014FB00 50 60 2E B4 */ rlwimi r0, r3, 5, 0x1a, 0x1a /* 80152BA4 0014FB04 98 1E 01 E5 */ stb r0, 0x1e5(r30) -.global lbl_80152BA8 lbl_80152BA8: /* 80152BA8 0014FB08 80 01 00 14 */ lwz r0, 0x14(r1) /* 80152BAC 0014FB0C 83 E1 00 0C */ lwz r31, 0xc(r1) @@ -4331,8 +4288,8 @@ lbl_80152BA8: /* 80152BB8 0014FB18 38 21 00 10 */ addi r1, r1, 0x10 /* 80152BBC 0014FB1C 4E 80 00 20 */ blr -.global "__ct__22CScriptSpecialFunctionF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fQ222CScriptSpecialFunction16ESpecialFunctionRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>ffffRC9CVector3fRC6CColorbRC11CDamageInfoUiUiUiUsUsUs" -"__ct__22CScriptSpecialFunctionF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fQ222CScriptSpecialFunction16ESpecialFunctionRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>ffffRC9CVector3fRC6CColorbRC11CDamageInfoUiUiUiUsUsUs": +.global "__ct__22CScriptSpecialFunctionF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fQ222CScriptSpecialFunction16ESpecialFunctionRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>ffffRC9CVector3fRC6CColorbRC11CDamageInfollQ212CPlayerState9EItemTypesss" +"__ct__22CScriptSpecialFunctionF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fQ222CScriptSpecialFunction16ESpecialFunctionRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>ffffRC9CVector3fRC6CColorbRC11CDamageInfollQ212CPlayerState9EItemTypesss": /* 80152BC0 0014FB20 94 21 FE 70 */ stwu r1, -0x190(r1) /* 80152BC4 0014FB24 7C 08 02 A6 */ mflr r0 /* 80152BC8 0014FB28 90 01 01 94 */ stw r0, 0x194(r1) diff --git a/include/Kyoto/Audio/CSfxManager.hpp b/include/Kyoto/Audio/CSfxManager.hpp index 2c66b839..9ee1dd8a 100644 --- a/include/Kyoto/Audio/CSfxManager.hpp +++ b/include/Kyoto/Audio/CSfxManager.hpp @@ -9,7 +9,16 @@ class CSfxManager { public: static void Update(f32 dt); static void RemoveEmitter(CSfxHandle handle); + static void UpdateEmitter(const CSfxHandle& handle, const CVector3f& pos, const CVector3f& dir, + uchar maxVol); + static CSfxHandle AddEmitter(u16 id, const CVector3f& pos, const CVector3f& dir, + bool useAcoustics, bool looped, s16 prio, s32 areaId); + static CSfxHandle AddEmitter(u16 id, const CVector3f& pos, const CVector3f& dir, uchar vol, + bool useAcoustics, bool looped, s16 prio, s32 areaId); static void Shutdown(); + static u16 TranslateSFXID(u16); + + static void PitchBend(const CSfxHandle& handle, float pitch); }; #endif diff --git a/include/Kyoto/Math/CVector2i.hpp b/include/Kyoto/Math/CVector2i.hpp index 2d3967ed..ef7196ee 100644 --- a/include/Kyoto/Math/CVector2i.hpp +++ b/include/Kyoto/Math/CVector2i.hpp @@ -4,6 +4,9 @@ #include "types.h" class CVector2i { +public: + CVector2i(int, int); + private: int x; int y; diff --git a/include/MetroidPrime/CActor.hpp b/include/MetroidPrime/CActor.hpp index f38f712b..86fa7dac 100644 --- a/include/MetroidPrime/CActor.hpp +++ b/include/MetroidPrime/CActor.hpp @@ -267,6 +267,7 @@ public: } CVector3f GetTranslation() const { return x34_transform.GetTranslation(); } void SetTranslation(const CVector3f& vec); + CTransform4f GetScaledLocatorTransform(const rstl::string& segName) const; /// ???? bool NullModel() const { return !GetAnimationData() && !GetModelData()->HasNormalModel(); } @@ -318,6 +319,17 @@ public: void SetMuted(bool b) { xe5_26_muted = b; } void SetRenderParticleDatabaseInside(bool b) { xe6_29_renderParticleDBInside = b; } + void RemoveMaterial(EMaterialTypes, EMaterialTypes, EMaterialTypes, EMaterialTypes, CStateManager&); + void RemoveMaterial(EMaterialTypes, EMaterialTypes, EMaterialTypes, CStateManager&); + void RemoveMaterial(EMaterialTypes, EMaterialTypes, CStateManager&); + void RemoveMaterial(EMaterialTypes, CStateManager&); + void AddMaterial(EMaterialTypes, EMaterialTypes, EMaterialTypes, EMaterialTypes, EMaterialTypes, CStateManager&); + void AddMaterial(EMaterialTypes, EMaterialTypes, EMaterialTypes, EMaterialTypes, CStateManager&); + void AddMaterial(EMaterialTypes, EMaterialTypes, EMaterialTypes, CStateManager&); + void AddMaterial(EMaterialTypes, EMaterialTypes, CStateManager&); + void AddMaterial(EMaterialTypes, CStateManager&); + void AddMaterial(const CMaterialList& l); + const CAABox& GetRenderBoundsCached() const { return x9c_renderBounds; } void SetRenderBounds(const CAABox& bounds) { x9c_renderBounds = bounds; } diff --git a/include/MetroidPrime/CEntity.hpp b/include/MetroidPrime/CEntity.hpp index ff9c5946..8e9cd4e7 100644 --- a/include/MetroidPrime/CEntity.hpp +++ b/include/MetroidPrime/CEntity.hpp @@ -28,7 +28,9 @@ public: mgr.SendScriptMsg(to, sender, msg); } TUniqueId GetUniqueId() const { return x8_uid; } + TEditorId GetEditorId() const { return xc_editorId; } TAreaId GetAreaId() const; + TAreaId GetAreaIdAlways() const { return x4_areaId; } bool GetActive() const { return x30_24_active; } // might be fake? diff --git a/include/MetroidPrime/CEnvFxManager.hpp b/include/MetroidPrime/CEnvFxManager.hpp index 43a9978e..9929e9d2 100644 --- a/include/MetroidPrime/CEnvFxManager.hpp +++ b/include/MetroidPrime/CEnvFxManager.hpp @@ -37,6 +37,7 @@ private: class CEnvFxManager { public: static void Initialize(); + void SetFxDensity(s32, float); private: CAABox x0_particleBounds; diff --git a/include/MetroidPrime/CMain.hpp b/include/MetroidPrime/CMain.hpp index ec32f8bc..d69e0569 100644 --- a/include/MetroidPrime/CMain.hpp +++ b/include/MetroidPrime/CMain.hpp @@ -78,6 +78,7 @@ public: bool CheckTerminate(); bool CheckReset(); void OpenWindow(); + void SetFlowState(EFlowState s) { x12c_flowState = s; } void SetMaxSpeed(bool v) { // ? diff --git a/include/MetroidPrime/CMemoryCard.hpp b/include/MetroidPrime/CMemoryCard.hpp index c6dd731d..9bcc0d21 100644 --- a/include/MetroidPrime/CMemoryCard.hpp +++ b/include/MetroidPrime/CMemoryCard.hpp @@ -3,10 +3,15 @@ #include "types.h" +#include "MetroidPrime/TGameTypes.hpp" +#include "Kyoto/CObjectReference.hpp" + class CMemoryCard { public: ~CMemoryCard(); // TODO + + rstl::pair GetAreaAndWorldIdForSaveId(s32 saveId) const; }; extern CMemoryCard* gpMemoryCard; diff --git a/include/MetroidPrime/CModelData.hpp b/include/MetroidPrime/CModelData.hpp index a23160cc..375cc1ae 100644 --- a/include/MetroidPrime/CModelData.hpp +++ b/include/MetroidPrime/CModelData.hpp @@ -39,6 +39,7 @@ public: }; // TODO these probably aren't real + bool HasAnimData() const { return xc_animData.get() != nullptr; } bool HasNormalModel() const { return x1c_normalModel; } CModelData(); @@ -74,6 +75,9 @@ public: bool GetSortThermal() const { return x14_25_sortThermal; } void SetSortThermal(bool b) { x14_25_sortThermal = b; } + const CVector3f& GetScale() const { return x0_scale; } + void SetScale(const CVector3f& scale) { x0_scale = scale; } + static CModelData CModelDataNull(); static EWhichModel GetRenderingModel(const CStateManager& mgr); diff --git a/include/MetroidPrime/CPhysicsActor.hpp b/include/MetroidPrime/CPhysicsActor.hpp index 8acf29ba..57e63a11 100644 --- a/include/MetroidPrime/CPhysicsActor.hpp +++ b/include/MetroidPrime/CPhysicsActor.hpp @@ -67,6 +67,7 @@ public: CAABox GetBoundingBox() const; void MoveCollisionPrimitive(const CVector3f&); + void SetAngularVelocityWR(const CAxisAngle& angVel); void Stop(); CMotionState GetMotionState() const; diff --git a/include/MetroidPrime/CStateManager.hpp b/include/MetroidPrime/CStateManager.hpp index e95f7f0e..beba4eb3 100644 --- a/include/MetroidPrime/CStateManager.hpp +++ b/include/MetroidPrime/CStateManager.hpp @@ -3,7 +3,10 @@ #include "types.h" +#include "Kyoto/CObjectReference.hpp" #include "Kyoto/CRandom16.hpp" +#include "Kyoto/Math/CVector2i.hpp" +#include "Kyoto/TToken.hpp" #include "MetroidPrime/CEntityInfo.hpp" #include "MetroidPrime/CObjectList.hpp" #include "MetroidPrime/TGameTypes.hpp" @@ -36,6 +39,10 @@ class CEntity; class CMazeState; class CRayCastResult; class CMaterialFilter; +class CScriptLayerManager; +class CLight; +class CDamageInfo; +class CTexture; namespace SL { class CSortedListManager; @@ -44,8 +51,24 @@ class CSortedListManager; #define kMaxEntities 1024 typedef rstl::reserved_vector< TUniqueId, kMaxEntities > TEntityList; +enum EStateManagerTransition { + kSMT_InGame, + kSMT_MapScreen, + kSMT_PauseGame, + kSMT_LogBook, + kSMT_SaveGame, + kSMT_MessageScreen +}; + +struct SOnScreenTex { + CAssetId x0_id; + CVector2i x4_origin; + CVector2i xc_extent; +}; + class CStateManager { public: + void ResetEscapeSequenceTimer(float); void SendScriptMsg(TUniqueId uid, TEditorId target, EScriptObjectMessage msg, EScriptObjectState state); void SendScriptMsg(CEntity* ent, TUniqueId target, EScriptObjectMessage msg); @@ -65,6 +88,7 @@ public: CEntity* ObjectById(TUniqueId uid); const CEntity* GetObjectById(TUniqueId uid) const; TUniqueId GetIdForScript(TEditorId eid) const; + // GetIdListForScript(TEditorId) const; CMazeState* CurrentMaze(); const CMazeState* GetCurrentMaze() const; @@ -82,6 +106,9 @@ public: const CActorModelParticles* GetActorModelParticles() const { return x884_actorModelParticles.get(); } + CEnvFxManager* EnvFxManager() { return x880_envFxManager; } + const CEnvFxManager* GetEnvFxManager() const { return x880_envFxManager; } + CRandom16* GetActiveRandom() const { return x900_random; } CObjectList& GetObjectListById(EGameObjectList id) { return *x808_objectLists[id]; } @@ -100,6 +127,30 @@ public: return objUid; } + void ApplyDamageToWorld(TUniqueId, const CActor&, const CVector3f&, const CDamageInfo& info, + CMaterialFilter&); + bool ApplyDamage(TUniqueId damagerId, TUniqueId damageeId, TUniqueId radiusSender, + const CDamageInfo& info, const CMaterialFilter& filter, + const CVector3f& knockbackVec); + + void DeferStateTransition(EStateManagerTransition t); + EStateManagerTransition GetDeferredStateTransition() const { return xf90_deferredTransition; } + void SetBossParams(TUniqueId bossId, float maxEnergy, u32 stringIdx); + void SetPendingOnScreenTex(CAssetId texId, const CVector2i& origin, const CVector2i& extent) { + xef4_pendingScreenTex.x0_id = texId; + xef4_pendingScreenTex.x4_origin = origin; + xef4_pendingScreenTex.xc_extent = extent; + } + const SOnScreenTex& GetPendingScreenTex() const { return xef4_pendingScreenTex; } + + void SetShouldQuitGame(bool should) { xf94_25_quitGame = should; } + void SetSkipCinematicSpecialFunction(TUniqueId id) { /*xf38_skipCineSpecialFunc = id;*/ + } + void SetInSaveUI(bool b) { xf94_28_inSaveUI = b; } + bool GetInSaveUI() const { return xf94_28_inSaveUI; } + void SetIsFullThreat(bool v) { xf94_30_fullThreat = v; } + u32 GetInputFrameIdx() const { return x8d4_inputFrameIdx; } + private: u16 x0_nextFreeIndex; rstl::reserved_vector< u16, 1024 > x8_objectIndexArray; @@ -123,12 +174,29 @@ private: rstl::rc_ptr< CScriptMailbox > x8bc_mailbox; rstl::rc_ptr< CMapWorldInfo > x8c0_mapWorldInfo; rstl::rc_ptr< CWorldTransManager > x8c4_worldTransManager; - u8 pad2[0x38]; + rstl::rc_ptr< CScriptLayerManager > x8c8_worldLayerState; + + TAreaId x8cc_nextAreaId; + TAreaId x8d0_prevAreaId; + u32 x8d4_inputFrameIdx; + u32 x8d8_updateFrameIdx; + u32 x8dc_objectDrawToken; + + rstl::vector< CLight > x8e0_dynamicLights; + + TLockedToken< CTexture > x8f0_shadowTex; CRandom16* x900_random; - u8 pad4[0x61c]; + + u8 x904_pad[0x5f0]; + + SOnScreenTex xef4_pendingScreenTex; + + u8 xf08_pad[0x1C]; + f32 xf24_thermColdScale1; f32 xf28_thermColdScale2; - u8 pad3[0x6c]; + u8 pad3[0x68]; + EStateManagerTransition xf90_deferredTransition; bool xf94_24_readyToRender : 1; bool xf94_25_quitGame : 1; bool xf94_26_generatingObject : 1; diff --git a/include/MetroidPrime/CWorld.hpp b/include/MetroidPrime/CWorld.hpp index a2995182..e8c0e37b 100644 --- a/include/MetroidPrime/CWorld.hpp +++ b/include/MetroidPrime/CWorld.hpp @@ -3,6 +3,7 @@ #include "types.h" +#include "MetroidPrime/CGameArea.hpp" #include "MetroidPrime/TGameTypes.hpp" #include "Kyoto/IObjectStore.hpp" @@ -60,6 +61,8 @@ public: const CGameArea& GetAreaAlways(TAreaId id) const { return *x18_areas[id.Value()]; } const CGameArea* GetArea(TAreaId id) const { return x18_areas[id.Value()].get(); } bool IsAreaValid(TAreaId id) const { return x18_areas[id.Value()]->IsLoaded(); } + CAssetId GetWorldAssetId() const { return x8_mlvlId; } + TAreaId GetAreaIdForSaveId(s32 saveId) const; private: enum Phase { diff --git a/include/MetroidPrime/Cameras/CCameraManager.hpp b/include/MetroidPrime/Cameras/CCameraManager.hpp index 6f11263d..21166c5b 100644 --- a/include/MetroidPrime/Cameras/CCameraManager.hpp +++ b/include/MetroidPrime/Cameras/CCameraManager.hpp @@ -25,6 +25,8 @@ public: CGameCamera* GetCurrentCamera(CStateManager& mgr) const; void SetPlayerCamera(CStateManager& mgr, TUniqueId newCamId); + void SetFogDensity(float fogDensityTarget, float fogDensitySpeed); + static f32 DefaultThirdPersonFov(); private: diff --git a/include/MetroidPrime/Player/CHintOptions.hpp b/include/MetroidPrime/Player/CHintOptions.hpp index cb8627ca..4f0ebbac 100644 --- a/include/MetroidPrime/Player/CHintOptions.hpp +++ b/include/MetroidPrime/Player/CHintOptions.hpp @@ -17,6 +17,10 @@ class CHintOptions { public: void SetHintNextTime(); + void DelayHint(const rstl::string& name); + void ActivateImmediateHintTimer(const rstl::string& name); + void ActivateContinueDelayHintTimer(const rstl::string& name); + private: rstl::vector< SHintState > x0_hintStates; int x10_nextHintIdx; diff --git a/include/MetroidPrime/Player/CPlayer.hpp b/include/MetroidPrime/Player/CPlayer.hpp index a222ce0a..89d999ea 100644 --- a/include/MetroidPrime/Player/CPlayer.hpp +++ b/include/MetroidPrime/Player/CPlayer.hpp @@ -152,6 +152,9 @@ public: CTransform4f CreateTransformFromMovementDirection() const; EPlayerOrbitState GetOrbitState() const { return x304_orbitState; } const CVector3f& GetMovementDirection() const { return x50c_moveDir; } + void SetHudDisable(float staticTimer, float outSpeed, float inSpeed); + void IncrementPhazon(); + void DecrementPhazon(); // GetMovementDirection2D__7CPlayerCFv ?? private: @@ -384,4 +387,4 @@ private: }; CHECK_SIZEOF(CPlayer, 0xa38) -#endif \ No newline at end of file +#endif diff --git a/include/MetroidPrime/Player/CPlayerState.hpp b/include/MetroidPrime/Player/CPlayerState.hpp index a2e459b6..363acce2 100644 --- a/include/MetroidPrime/Player/CPlayerState.hpp +++ b/include/MetroidPrime/Player/CPlayerState.hpp @@ -95,11 +95,11 @@ public: u32 GetMissileCostForAltAttack() const; float GetComboFireAmmoPeriod() const; static float GetMissileComboChargeFactor(); - u32 CalculateItemCollectionRate(); - u32 GetTotalPickupCount(); + u32 CalculateItemCollectionRate() const; + u32 GetTotalPickupCount() const; void SetIsFusionEnabled(bool v); - bool GetIsFusionEnabled(); + bool GetIsFusionEnabled() const; EPlayerSuit GetCurrentSuit(); EPlayerSuit GetCurrentSuitRaw() const { return x20_currentSuit; } diff --git a/include/MetroidPrime/Player/CSystemOptions.hpp b/include/MetroidPrime/Player/CSystemOptions.hpp index d13316d6..573f6c8a 100644 --- a/include/MetroidPrime/Player/CSystemOptions.hpp +++ b/include/MetroidPrime/Player/CSystemOptions.hpp @@ -16,6 +16,9 @@ public: void SetHasFusion(bool v); bool GetHasFusion() const { return xd0_28_fusionSuitActive; } + bool GetCinematicState(CAssetId mlvlId, TEditorId cineId) const; + void SetCinematicState(CAssetId mlvlId, TEditorId cineId, bool state); + private: rstl::reserved_vector< u8, 98 > x0_nesState; rstl::reserved_vector< bool, 64 > x68_; diff --git a/include/MetroidPrime/ScriptObjects/CScriptSpecialFunction.hpp b/include/MetroidPrime/ScriptObjects/CScriptSpecialFunction.hpp new file mode 100644 index 00000000..9b3c534f --- /dev/null +++ b/include/MetroidPrime/ScriptObjects/CScriptSpecialFunction.hpp @@ -0,0 +1,150 @@ +#ifndef _CSCRIPTSPECIALFUNCTION_HPP +#define _CSCRIPTSPECIALFUNCTION_HPP + +#include "MetroidPrime/CActor.hpp" +#include "MetroidPrime/CDamageInfo.hpp" + +#include "Kyoto/Graphics/CColor.hpp" +#include "Kyoto/Graphics/CTexture.hpp" +#include "Kyoto/Math/CAABox.hpp" +#include "Kyoto/Math/CTransform4f.hpp" +#include "Kyoto/Math/CVector3f.hpp" +#include "Kyoto/TReservedAverage.hpp" + +#include "MetroidPrime/Player/CPlayerState.hpp" + + +class CScriptSpecialFunction : public CActor { +public: + enum ESpecialFunction { + kSF_What = 0, + kSF_PlayerFollowLocator = 1, + kSF_SpinnerController = 2, + kSF_ObjectFollowLocator = 3, + kSF_ChaffTarget = 4, + kSF_InventoryActivator = 5, + kSF_MapStation = 6, + kSF_SaveStation = 7, + kSF_IntroBossRingController = 8, + kSF_ViewFrustumTester = 9, + kSF_ShotSpinnerController = 10, + kSF_EscapeSequence = 11, + kSF_BossEnergyBar = 12, + kSF_EndGame = 13, + kSF_HUDFadeIn = 14, + kSF_CinematicSkip = 15, + kSF_ScriptLayerController = 16, + kSF_RainSimulator = 17, + kSF_AreaDamage = 18, + kSF_ObjectFollowObject = 19, + kSF_RedundantHintSystem = 20, + kSF_DropBomb = 21, + kSF_ScaleActor = 22, + kSF_MissileStation = 23, + kSF_Billboard = 24, + kSF_PlayerInAreaRelay = 25, + kSF_HUDTarget = 26, + kSF_FogFader = 27, + kSF_EnterLogbook = 28, + kSF_PowerBombStation = 29, + kSF_Ending = 30, + kSF_FusionRelay = 31, + kSF_WeaponSwitch = 32, + kSF_FogVolume = 47, + kSF_RadialDamage = 48, + kSF_EnvFxDensityController = 49, + kSF_RumbleEffect = 50 + }; + + enum ESpinnerControllerMode { + kSCM_Zero, + kSCM_One, + }; + + enum ERingState { kRS_Scramble, kRS_Rotate, kRS_Stopped, kRS_Breakup }; + + struct SRingController { + TUniqueId x0_id; + float x4_rotateSpeed; + bool x8_reachedTarget; + CVector3f xc_; + SRingController(TUniqueId uid, float rotateSpeed, bool reachedTarget); + }; + +private: + ESpecialFunction xe8_function; + rstl::string xec_locatorName; + float xfc_float1; + float x100_float2; + float x104_float3; + float x108_float4; + CVector3f x10c_vector3f; + CColor x118_color; + CDamageInfo x11c_damageInfo; + float x138_; + CTransform4f x13c_spinnerInitialXf; + float x16c_; + u16 x170_sfx1; + u16 x172_sfx2; + u16 x174_sfx3; + CSfxHandle x178_sfxHandle; + u32 x17c_; + float x180_; + TReservedAverage x184_; // metaforce has this as TReservedAverage, but volume is uchar here + u8 x190_pad[4]; // type change in x184_ fixes it being too big, but then it becomes 4 bytes too small + float x194_; + rstl::vector x198_ringControllers; + ERingState x1a8_ringState; + CVector3f x1ac_ringRotateTarget; + bool x1b8_ringReverse; + s32 x1bc_areaSaveId; + s32 x1c0_layerIdx; + CPlayerState::EItemType x1c4_item; + rstl::optional_object x1c8_touchBounds; + bool x1e4_24_spinnerInitializedXf : 1; + bool x1e4_25_spinnerCanMove : 1; + bool x1e4_26_sfx2Played : 1; + bool x1e4_27_sfx3Played : 1; + bool x1e4_28_frustumEntered : 1; + bool x1e4_29_frustumExited : 1; + bool x1e4_30_ : 1; + bool x1e4_31_inAreaDamage : 1; + bool x1e5_24_doSave : 1; + bool x1e5_25_playerInArea : 1; + bool x1e5_26_displayBillboard : 1; + rstl::optional_object x1e8_; // CTexture? +public: + CScriptSpecialFunction(TUniqueId, const rstl::string&, const CEntityInfo&, const CTransform4f&, ESpecialFunction, + const rstl::string&, float, float, float, float, const CVector3f&, const CColor&, + bool, const CDamageInfo&, s32, s32, CPlayerState::EItemType, s16, s16, s16); + + void Accept(IVisitor& visitor) override; + void Think(float, CStateManager&) override; + void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; + void PreRender(CStateManager&, const CFrustumPlanes&) override; + void AddToRenderer(const CFrustumPlanes&, CStateManager&) override; + void Render(CStateManager&) override; + rstl::optional_object GetTouchBounds() const override { return x1c8_touchBounds; } + + void SkipCinematic(CStateManager&); + void RingScramble(CStateManager&); + void ThinkIntroBossRingController(float, CStateManager&); + void ThinkPlayerFollowLocator(float, CStateManager&); + void ThinkSpinnerController(float, CStateManager&, ESpinnerControllerMode); + void ThinkObjectFollowLocator(float, CStateManager&); + void ThinkObjectFollowObject(float, CStateManager&); + void ThinkChaffTarget(float, CStateManager&); + void ThinkActorScale(float, CStateManager&); + void ThinkSaveStation(float, CStateManager&); + void ThinkRainSimulator(float, CStateManager&); + void ThinkAreaDamage(float, CStateManager&); + void ThinkPlayerInArea(float, CStateManager&); + + bool ShouldSkipCinematic(CStateManager& stateMgr) const; + + void DeleteEmitter(const CSfxHandle& handle); + u32 GetSpecialEnding(const CStateManager&) const; + void AddOrUpdateEmitter(float pitch, CSfxHandle& handle, u16 id, const CVector3f& pos, uchar vol); +}; + +#endif _CSCRIPTSPECIALFUNCTION_HPP diff --git a/src/MetroidPrime/Player/CPlayerState.cpp b/src/MetroidPrime/Player/CPlayerState.cpp index a59c2077..bb3dae91 100644 --- a/src/MetroidPrime/Player/CPlayerState.cpp +++ b/src/MetroidPrime/Player/CPlayerState.cpp @@ -362,13 +362,13 @@ CPlayerState::EPlayerSuit CPlayerState::GetCurrentSuit() { return x20_currentSuit; } -bool CPlayerState::GetIsFusionEnabled() { return x0_26_fusion; } +bool CPlayerState::GetIsFusionEnabled() const { return x0_26_fusion; } void CPlayerState::SetIsFusionEnabled(bool val) { x0_26_fusion = val; } -u32 CPlayerState::GetTotalPickupCount() { return 99; } +u32 CPlayerState::GetTotalPickupCount() const { return 99; } -u32 CPlayerState::CalculateItemCollectionRate() { +u32 CPlayerState::CalculateItemCollectionRate() const { u32 total = GetItemCapacity(kIT_PowerBombs); if (total >= 4) @@ -416,4 +416,3 @@ float CPlayerState::GetComboFireAmmoPeriod() const { } float CPlayerState::GetMissileComboChargeFactor() { return 1.8f; } - diff --git a/src/MetroidPrime/ScriptObjects/CScriptSpecialFunction.cpp b/src/MetroidPrime/ScriptObjects/CScriptSpecialFunction.cpp new file mode 100644 index 00000000..c0a5a749 --- /dev/null +++ b/src/MetroidPrime/ScriptObjects/CScriptSpecialFunction.cpp @@ -0,0 +1,1060 @@ +#include "MetroidPrime/ScriptObjects/CScriptSpecialFunction.hpp" + +#include "MetroidPrime/CActorParameters.hpp" +#include "MetroidPrime/CEnvFxManager.hpp" +#include "MetroidPrime/CMain.hpp" +#include "MetroidPrime/CStateManager.hpp" +#include "MetroidPrime/CWorld.hpp" +#include "MetroidPrime/Cameras/CCameraManager.hpp" +#include "MetroidPrime/Player/CGameState.hpp" +#include "MetroidPrime/Player/CPlayer.hpp" +#include "MetroidPrime/Player/CPlayerState.hpp" +#include "MetroidPrime/TCastTo.hpp" + +#include "Collision/CMaterialFilter.hpp" + +#include "Kyoto/Audio/CSfxManager.hpp" +#include "Kyoto/Math/CFrustumPlanes.hpp" +#include "Kyoto/Math/CMath.hpp" +#include "Kyoto/Math/CVector2i.hpp" + +#include "rstl/math.hpp" + +CScriptSpecialFunction::CScriptSpecialFunction( + TUniqueId uid, const rstl::string& name, const CEntityInfo& info, const CTransform4f& xf, + ESpecialFunction func, const rstl::string& lcName, float f1, float f2, float f3, float f4, + const CVector3f& vec, const CColor& col, bool active, const CDamageInfo& dInfo, s32 aId1, + s32 aId2, CPlayerState::EItemType itemType, s16 sId1, s16 sId2, s16 sId3) +: CActor(uid, active, name, info, xf, CModelData::CModelDataNull(), CMaterialList(), + CActorParameters::None(), kInvalidUniqueId) +, xe8_function(func) +, xec_locatorName(lcName) +, xfc_float1(f1) +, x100_float2(f2) +, x104_float3(f3) +, x108_float4(f4) +, x10c_vector3f(vec) +, x118_color(col) +, x11c_damageInfo(dInfo) +, x13c_spinnerInitialXf(CTransform4f::Identity()) +, x170_sfx1(CSfxManager::TranslateSFXID(sId1)) +, x172_sfx2(CSfxManager::TranslateSFXID(sId2)) +, x174_sfx3(CSfxManager::TranslateSFXID(sId3)) +, x184_(0.f) +, x1ac_ringRotateTarget(CVector3f::Zero()) +, x1bc_areaSaveId(aId1) +, x1c0_layerIdx(aId2) +, x1c4_item(itemType) { + if (xe8_function == kSF_HUDTarget) { + x1c8_touchBounds = CAABox(CVector3f(-1.f, -1.f, -1.f), CVector3f(1.f, 1.f, 1.f)); + } +} + +void CScriptSpecialFunction::Accept(IVisitor& visitor) { visitor.Visit(*this); } + +void CScriptSpecialFunction::Think(float dt, CStateManager& mgr) { + if (!GetActive()) { + return; + } + + switch (xe8_function) { + case kSF_PlayerFollowLocator: + ThinkPlayerFollowLocator(dt, mgr); + break; + case kSF_SpinnerController: + ThinkSpinnerController(dt, mgr, kSCM_Zero); + break; + case kSF_ShotSpinnerController: + ThinkSpinnerController(dt, mgr, kSCM_One); + break; + case kSF_ObjectFollowLocator: + ThinkObjectFollowLocator(dt, mgr); + break; + case kSF_ObjectFollowObject: + ThinkObjectFollowObject(dt, mgr); + break; + case kSF_ChaffTarget: + ThinkChaffTarget(dt, mgr); + break; + case kSF_ViewFrustumTester: { + if (x1e4_28_frustumEntered) { + x1e4_28_frustumEntered = false; + SendScriptMsgs(kSS_Entered, mgr, kSM_None); + } + if (x1e4_29_frustumExited) { + x1e4_29_frustumExited = false; + SendScriptMsgs(kSS_Exited, mgr, kSM_None); + } + break; + } + case kSF_SaveStation: + ThinkSaveStation(dt, mgr); + break; + case kSF_IntroBossRingController: + ThinkIntroBossRingController(dt, mgr); + break; + case kSF_RainSimulator: + ThinkRainSimulator(dt, mgr); + break; + case kSF_AreaDamage: + ThinkAreaDamage(dt, mgr); + break; + case kSF_ScaleActor: + ThinkActorScale(dt, mgr); + break; + case kSF_PlayerInAreaRelay: + ThinkPlayerInArea(dt, mgr); + break; + case kSF_Billboard: { + if (x1e8_.valid() && x1e8_.data().IsLoaded() && x1e5_26_displayBillboard) { + SendScriptMsgs(kSS_MaxReached, mgr, kSM_None); + x1e5_26_displayBillboard = false; + } + break; + } + default: + break; + } +} + +// constexpr std::array fxTranslation{ +// ERumbleFxId::Twenty, ERumbleFxId::One, ERumbleFxId::TwentyOne, +// ERumbleFxId::TwentyTwo, ERumbleFxId::TwentyThree, ERumbleFxId::Zero, +// }; + +void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, + CStateManager& mgr) { + if (GetActive() && msg == kSM_Deactivate && xe8_function == kSF_Billboard) { + mgr.SetPendingOnScreenTex(CAssetId(), CVector2i(0, 0), CVector2i(0, 0)); + if (x1e8_) { + x1e8_.clear(); + } + x1e5_26_displayBillboard = false; + } + CActor::AcceptScriptMsg(msg, uid, mgr); + + if (xe8_function == kSF_ChaffTarget && msg == kSM_InitializedInArea) { + AddMaterial(kMT_Target, mgr); + } + + if (GetActive()) { + switch (xe8_function) { + case kSF_HUDFadeIn: { + if (msg == kSM_Action) { + mgr.Player()->SetHudDisable(xfc_float1, 0.f, 0.5f); + } + break; + } + case kSF_EscapeSequence: { + if (msg == kSM_Action && xfc_float1 >= 0.f) { + mgr.ResetEscapeSequenceTimer(xfc_float1); + } + break; + } + case kSF_SpinnerController: { + switch (msg) { + case kSM_Stop: { + x1e4_25_spinnerCanMove = false; + break; + } + case kSM_Play: { + x1e4_25_spinnerCanMove = true; + mgr.Player()->SetAngularVelocityWR(CAxisAngle::Identity()); + break; + } + case kSM_Deactivate: + DeleteEmitter(x178_sfxHandle); + break; + default: + break; + } + break; + } + case kSF_ShotSpinnerController: { + switch (msg) { + case kSM_Increment: { + + x16c_ = CMath::Clamp(0.f, x16c_ + 1.f, 1.f); + SendScriptMsgs(kSS_Play, mgr, kSM_None); + break; + } + case kSM_SetToMax: { + x16c_ = x104_float3; + SendScriptMsgs(kSS_Play, mgr, kSM_None); + break; + } + case kSM_SetToZero: { + x16c_ = -0.5f * x104_float3; + break; + } + default: + break; + } + break; + } + case kSF_MapStation: { + if (msg == kSM_Action) { + // TODO + // mgr.MapWorldInfo()->SetMapStationUsed(true); + // mgr.GetWorld()->GetMapWorld()->RecalculateWorldSphere(*mgr.MapWorldInfo(), + // *mgr.GetWorld()); + } + break; + } + case kSF_MissileStation: { + if (msg == kSM_Action) { + CPlayerState& pState = *mgr.PlayerState(); + pState.ResetAndIncrPickUp(CPlayerState::kIT_Missiles, + pState.GetItemCapacity(CPlayerState::kIT_Missiles)); + } + break; + } + case kSF_PowerBombStation: { + if (msg == kSM_Action) { + CPlayerState& pState = *mgr.PlayerState(); + pState.ResetAndIncrPickUp(CPlayerState::kIT_PowerBombs, + pState.GetItemCapacity(CPlayerState::kIT_PowerBombs)); + } + break; + } + case kSF_SaveStation: { + if (msg == kSM_Action) { + mgr.PlayerState()->IncrPickUp(CPlayerState::kIT_EnergyTanks, 1); + if (gpGameState->CardSerial() == 0) { + SendScriptMsgs(kSS_Closed, mgr, kSM_None); + } else { + mgr.DeferStateTransition(kSMT_SaveGame); + x1e5_24_doSave = true; + } + } + break; + } + case kSF_IntroBossRingController: { + if (x1a8_ringState != kRS_Breakup) { + switch (msg) { + case kSM_Play: { + if (x1a8_ringState != kRS_Scramble) { + RingScramble(mgr); + } + + for (rstl::vector< SRingController >::iterator rc = x198_ringControllers.begin(); + rc != x198_ringControllers.end(); ++rc) { + if (CActor* act = TCastToPtr< CActor >(mgr.ObjectById(rc->x0_id))) { + rc->xc_ = act->GetTransform().GetForward(); + } else { + rc->xc_ = CVector3f::Forward(); + } + } + + x1a8_ringState = kRS_Breakup; + break; + } + case kSM_SetToZero: { + x1a8_ringState = kRS_Rotate; + x1ac_ringRotateTarget = GetTranslation() - mgr.GetPlayer()->GetTranslation(); + x1ac_ringRotateTarget.SetZ(0.f); + x1ac_ringRotateTarget.Normalize(); + break; + } + case kSM_Action: { + RingScramble(mgr); + break; + } + case kSM_InitializedInArea: { + x198_ringControllers.reserve(3); + + for (rstl::vector< SConnection >::const_iterator conn = GetConnectionList().begin(); + conn != GetConnectionList().end(); ++conn) { + if (conn->x0_state != kSS_Play || conn->x4_msg != kSM_Activate) { + continue; + } + + // GetIdListForScript seems very different between Ghidra and Metaforce + // const auto search = mgr.GetIdListForScript(conn->x8_objId); + + rstl::pair< TUniqueId, TUniqueId >* it; + if (CActor* act = TCastToPtr< CActor >(mgr.ObjectById(it->second))) { + x198_ringControllers.push_back(SRingController(it->second, 0.f, false)); + act->RemoveMaterial(kMT_Occluder, mgr); + } + } + + // TODO: there's an actual sort symbol, so it's a templated sort somewhere + // std::sort(x198_ringControllers.begin(), x198_ringControllers.end(), + // [&mgr](const SRingController& a, const SRingController& b) { + // const TCastToConstPtr actA(mgr.GetObjectById(a.x0_id)); + // const TCastToConstPtr actB(mgr.GetObjectById(b.x0_id)); + // if (actA && actB) { + // return actA->GetTranslation().z() < actB->GetTranslation().z(); + // } + // return false; + // }); + + for (rstl::vector< SRingController >::iterator rc = x198_ringControllers.begin(); + rc != x198_ringControllers.end(); ++rc) { + rc->x4_rotateSpeed = (x1b8_ringReverse ? 1.f : -1.f) * xfc_float1; + rc->x8_reachedTarget = false; + } + break; + } + default: + break; + } + } + break; + } + case kSF_RadialDamage: { + if (msg == kSM_Action) { + CMaterialList includeList(kMT_Solid); + CMaterialList excudeList(0); + CMaterialFilter filter(CMaterialFilter::MakeIncludeExclude(includeList, excudeList)); + + CDamageInfo dInfo = x11c_damageInfo; + dInfo.SetRadius(xfc_float1); + mgr.ApplyDamageToWorld(GetUniqueId(), *this, GetTranslation(), dInfo, filter); + } + break; + } + case kSF_BossEnergyBar: { + if (msg == kSM_Increment) { + mgr.SetBossParams(uid, xfc_float1, u32(x100_float2) + 86); + } else if (msg == kSM_Decrement) { + mgr.SetBossParams(kInvalidUniqueId, 0.f, 0); + } + break; + } + case kSF_EndGame: { + if (msg == kSM_Action) { + switch (GetSpecialEnding(mgr)) { + case 0: + gpMain->SetFlowState(kFS_WinBad); + break; + case 1: + gpMain->SetFlowState(kFS_WinGood); + break; + case 2: + gpMain->SetFlowState(kFS_WinBest); + break; + } + mgr.SetShouldQuitGame(true); + } + break; + } + case kSF_CinematicSkip: { + if (msg == kSM_Increment) { + if (ShouldSkipCinematic(mgr)) { + mgr.SetSkipCinematicSpecialFunction(GetUniqueId()); + } + } else if (msg == kSM_Decrement) { + mgr.SetSkipCinematicSpecialFunction(kInvalidUniqueId); + gpGameState->SystemOptions().SetCinematicState(mgr.GetWorld()->GetWorldAssetId(), + GetEditorId(), true); + } + break; + } + case kSF_ScriptLayerController: { + if (msg == kSM_Decrement || msg == kSM_Increment) { + if (x1bc_areaSaveId != -1 && x1c0_layerIdx != -1) { + TAreaId aId = mgr.GetWorld()->GetAreaIdForSaveId(x1bc_areaSaveId); + rstl::rc_ptr worldLayerState(NULL); + + if (aId != kInvalidAreaId) { + // worldLayerState = mgr.WorldLayerState(); + } else { + const rstl::pair worldAreaPair = gpMemoryCard->GetAreaAndWorldIdForSaveId(x1bc_areaSaveId); + + if (worldAreaPair.first != kInvalidAssetId) { + // worldLayerState = gpGameState->StateForWorld(worldAreaPair.first).GetLayerState(); + aId = worldAreaPair.second; + } + } + + if (aId != kInvalidAreaId) { + // TODO + // worldLayerState->SetLayerActive(aId, x1c0_layerIdx, msg == kSM_Increment); + } + } + } + /* + For some bizarre reason ScriptLayerController drops into EnvFxDensityController + */ + } + case kSF_EnvFxDensityController: { + if (msg == kSM_Action) { + mgr.EnvFxManager()->SetFxDensity(s32(x100_float2), xfc_float1); + } + break; + } + case kSF_RumbleEffect: + if (msg == kSM_Action) { + const s32 rumbFx = s32(x100_float2); + + // Retro originally did not check the upper bounds, this could potentially cause a crash + // with some runtimes, so let's make sure we're not out of bounds in either direction. + // if (rumbFx < 0 || rumbFx >= 6) { + // break; + // } + + // TODO: add fxTranslation + // mgr.GetRumbleManager().Rumble(mgr, fxTranslation[rumbFx], 1.f, kRP_One); + } + break; + case kSF_InventoryActivator: { + if (msg == kSM_Action && mgr.GetPlayerState()->HasPowerUp(x1c4_item)) { + SendScriptMsgs(kSS_Zero, mgr, kSM_None); + } + break; + } + case kSF_FusionRelay: { + if (msg == kSM_Action && mgr.GetPlayerState()->GetIsFusionEnabled()) { + SendScriptMsgs(kSS_Zero, mgr, kSM_None); + } + break; + } + case kSF_AreaDamage: { + if ((msg == kSM_Deleted || msg == kSM_Deactivate) && x1e4_31_inAreaDamage) { + x1e4_31_inAreaDamage = false; + mgr.Player()->DecrementPhazon(); + mgr.SetIsFullThreat(false); + } + break; + } + case kSF_DropBomb: { + if (msg == kSM_Action) { + if (xfc_float1 >= 1.f) { + // TODO: no CPlayerGun header + // mgr.Player()->PlayerGun()->DropBomb(CPlayerGun::EBWeapon::PowerBomb, mgr); + } else { + // mgr.Player()->PlayerGun()->DropBomb(CPlayerGun::EBWeapon::Bomb, mgr); + } + } + break; + } + case kSF_RedundantHintSystem: { + CHintOptions& hintOptions = gpGameState->HintOptions(); + if (msg == kSM_Action) { + hintOptions.ActivateContinueDelayHintTimer(xec_locatorName); + } else if (msg == kSM_Increment) { + hintOptions.ActivateImmediateHintTimer(xec_locatorName); + } else if (msg == kSM_Decrement) { + hintOptions.DelayHint(xec_locatorName); + } + break; + } + case kSF_Billboard: { + if (msg == kSM_Increment) { + const SObjectTag* objectTag = + gpResourceFactory->GetResourceIdByName(xec_locatorName.data()); + const CAssetId assetId = objectTag ? objectTag->id : kInvalidAssetId; + + mgr.SetPendingOnScreenTex(assetId, CVector2i(int(x104_float3), int(x108_float4)), + CVector2i(int(xfc_float1), int(x100_float2))); + if (objectTag) { + x1e8_ = gpSimplePool->GetObj(*objectTag); + x1e5_26_displayBillboard = true; + } + } else if (msg == kSM_Decrement) { + mgr.SetPendingOnScreenTex(kInvalidAssetId, CVector2i(int(x104_float3), int(x108_float4)), + CVector2i(int(xfc_float1), int(x100_float2))); + if (x1e8_) + x1e8_.clear(); + x1e5_26_displayBillboard = false; + } + break; + } + case kSF_PlayerInAreaRelay: { + if ((msg == kSM_Action || msg == kSM_SetToZero) && + GetAreaIdAlways() == mgr.GetPlayer()->GetAreaIdAlways()) { + SendScriptMsgs(kSS_Zero, mgr, kSM_None); + } + break; + } + case kSF_HUDTarget: { + if (msg == kSM_Increment) { + AddMaterial(kMT_Target, kMT_RadarObject, mgr); + } else if (msg == kSM_Decrement) { + RemoveMaterial(kMT_Target, kMT_RadarObject, mgr); + } + break; + } + case kSF_FogFader: { + if (msg == kSM_Increment) { + mgr.CameraManager()->SetFogDensity(x100_float2, xfc_float1); + } else if (msg == kSM_Decrement) { + mgr.CameraManager()->SetFogDensity(x100_float2, 1.f); + } + break; + } + case kSF_EnterLogbook: { + if (msg == kSM_Action) { + mgr.DeferStateTransition(kSMT_LogBook); + } + break; + } + case kSF_Ending: { + if (msg == kSM_Action && GetSpecialEnding(mgr) == u32(xfc_float1)) { + SendScriptMsgs(kSS_Zero, mgr, kSM_None); + } + break; + } + default: + break; + } + } +} + +void CScriptSpecialFunction::PreRender(CStateManager&, const CFrustumPlanes& frustum) { + if (xe8_function != kSF_FogVolume && xe8_function != kSF_ViewFrustumTester) { + return; + } + if (!GetActive()) { + return; + } + + bool val; + if (xe8_function == kSF_FogVolume) { + val = frustum.BoxInFrustumPlanes( + CAABox(GetTranslation() - x10c_vector3f, GetTranslation() + x10c_vector3f)); + } else { + val = frustum.PointInFrustumPlanes(GetTranslation()); + } + + if (x1e4_30_ == val) { + return; + } + if (!val) { + x1e4_29_frustumExited = true; + } else { + x1e4_28_frustumEntered = true; + } +} + +void CScriptSpecialFunction::AddToRenderer(const CFrustumPlanes&, CStateManager& mgr) { + if (!GetActive()) { + return; + } + + if (xe8_function == kSF_FogVolume && x1e4_30_) { + EnsureRendered(mgr); + } +} + +void CScriptSpecialFunction::Render(CStateManager& mgr) { + if (xe8_function == kSF_FogVolume) { + /* TODO + const float z = mgr.IntegrateVisorFog(xfc_float1 * std::sin(CGraphics::GetSecondsMod900())); + if (z > 0.f) { + CVector3f max = GetTranslation() + x10c_vector3f; + max.SetZ(max.GetZ() + z); + const CAABox box(GetTranslation() - x10c_vector3f, max); + const CTransform4f modelMtx = CTransform4f::Translate(box.center()) * + CTransform4f::Scale(box.extents()); g_Renderer->SetModelMatrix(modelMtx); + g_Renderer->RenderFogVolume(x118_color, zeus::CAABox(-1.f, 1.f), nullptr, nullptr); + } + */ + } else { + CActor::Render(mgr); + } +} + +void CScriptSpecialFunction::SkipCinematic(CStateManager& stateMgr) { + SendScriptMsgs(kSS_Zero, stateMgr, kSM_None); + stateMgr.SetSkipCinematicSpecialFunction(kInvalidUniqueId); +} + +void CScriptSpecialFunction::RingScramble(CStateManager& mgr) { + SendScriptMsgs(kSS_Zero, mgr, kSM_None); + x1a8_ringState = kRS_Scramble; + x1b8_ringReverse = !x1b8_ringReverse; + float dir = (x1b8_ringReverse ? 1.f : -1.f); + for (rstl::vector< SRingController >::iterator it = x198_ringControllers.begin(); + it != x198_ringControllers.end(); ++it) { + it->x4_rotateSpeed = dir * mgr.GetActiveRandom()->Range(x100_float2, x104_float3); + dir = -dir; + it->x8_reachedTarget = false; + } +} + +void CScriptSpecialFunction::ThinkIntroBossRingController(float dt, CStateManager& mgr) { + if (x1a8_ringState != kRS_Breakup) { + for (rstl::vector< SRingController >::iterator it = x198_ringControllers.begin(); + it != x198_ringControllers.end(); ++it) { + if (CActor* act = TCastToPtr< CActor >(mgr.ObjectById(it->x0_id))) { + CTransform4f newXf = act->GetTransform(); + // TODO + // newXf.rotateLocalZ(zeus::degToRad(it->x4_rotateSpeed * dt)); + act->SetTransform(newXf); + } + } + } + switch (x1a8_ringState) { + case kRS_Breakup: { + float minMag = 0.f; + for (rstl::vector< SRingController >::iterator it = x198_ringControllers.begin(); + it != x198_ringControllers.end(); ++it) { + if (CActor* act = TCastToPtr< CActor >(mgr.ObjectById(it->x0_id))) { + // TODO: CTransform api differences + // act->SetTranslation(act->GetTranform().basis[1] * 50.f * dt + act->GetTranslation()); + // minMag = std::min(act->GetTranslation().magnitude(), minMag); + } + } + CalculateRenderBounds(); + if (minMag != 0.f) { + /* Never actually happens */ + for (rstl::vector< SRingController >::iterator it = x198_ringControllers.begin(); + it != x198_ringControllers.end(); ++it) { + if (CEntity* ent = mgr.ObjectById(it->x0_id)) { + ent->SetActive(false); + } + } + SetActive(false); + } + break; + } + case kRS_Rotate: { + // x1ac_ringRotateTarget = CQuaternion::fromAxisAngle(zeus::skUp, zeus::degToRad(xfc_float1 * + // (x1b8_ringReverse ? 1.f : -1.f) * dt)) + // .transform(x1ac_ringRotateTarget); + bool allReachedTarget = true; + for (rstl::vector< SRingController >::iterator it = x198_ringControllers.begin(); + it != x198_ringControllers.end(); ++it) { + if (CActor* act = TCastToPtr< CActor >(mgr.ObjectById(it->x0_id))) { + /*CVector3f lookDirFlat = act->GetTransform().basis[1]; + lookDirFlat.SetZ(0.f); + lookDirFlat.Normalize(); + if (std::acos(CMath::Clamp(-1.f, lookDirFlat.Dot(x1ac_ringRotateTarget), 1.f)) <= + zeus::degToRad((xfc_float1 + std::fabs(rc.x4_rotateSpeed)) / 30.f)) { + CTransform4f newXf = zeus::lookAt(zeus::skZero3f, x1ac_ringRotateTarget); + newXf.origin = act->GetTranslation(); + act->SetTransform(newXf); + rc.x4_rotateSpeed = (x1b8_ringReverse ? 1.f : -1.f) * xfc_float1; + rc.x8_reachedTarget = true; + } else { + allReachedTarget = false; + break; + }*/ + } + } + if (allReachedTarget) { + SendScriptMsgs(kSS_MaxReached, mgr, kSM_None); + x1a8_ringState = kRS_Stopped; + for (rstl::vector< SRingController >::iterator it = x198_ringControllers.begin(); + it != x198_ringControllers.end(); ++it) { + it->x8_reachedTarget = false; + } + } + break; + } + default: + break; + } +} + +void CScriptSpecialFunction::ThinkPlayerFollowLocator(float, CStateManager& mgr) { + for (rstl::vector< SConnection >::const_iterator conn = GetConnectionList().begin(); + conn != GetConnectionList().end(); ++conn) { + if (conn->x0_state != kSS_Play || conn->x4_msg != kSM_Activate) { + continue; + } + + /* + const auto search = mgr.GetIdListForScript(conn->x8_objId); + for (auto it = search.first; it != search.second; ++it) { + if (const TCastToConstPtr act = mgr.GetObjectById(it->second)) { + const CTransform4f xf = act->GetTransform() * act->GetLocatorTransform(xec_locatorName); + CPlayer& pl = mgr.GetPlayer(); + pl.SetTransform(xf); + pl.SetVelocityWR({}); + pl.SetAngularVelocityWR({}); + pl.ClearForcesAndTorques(); + return; + } + } + */ + } +} + +void CScriptSpecialFunction::ThinkSpinnerController(float dt, CStateManager& mgr, + ESpinnerControllerMode mode) { + // rstl::string_find is found in CScriptSpecialFunction.s as sub_80150d98 + // const bool allowWrap = rstl::string_find(xec_locatorName, "AllowWrap") != std::string::npos; + // const bool noBackward = rstl::string_find(xec_locatorName, "NoBackward") != std::string::npos; + const float pointOneByDt = 0.1f * dt; + const float twoByDt = 2.f * dt; + + for (rstl::vector< SConnection >::const_iterator conn = GetConnectionList().begin(); + conn != GetConnectionList().end(); ++conn) { + if (conn->x0_state != kSS_Play || conn->x4_msg != kSM_Activate) { + continue; + } + + /* + const auto search = mgr.GetIdListForScript(conn->x8_objId); + for (auto it = search.first; it != search.second; ++it) { + if (const TCastToPtr plat = mgr.ObjectById((*it).second)) { + if (plat->HasModelData() && plat->GetModelData()->HasAnimData()) { + plat->SetControlledAnimation(true); + if (!x1e4_24_spinnerInitializedXf) { + x13c_spinnerInitialXf = plat->GetTransform(); + x1e4_24_spinnerInitializedXf = true; + } + + float f28 = x138_; + const float f29 = pointOneByDt * x100_float2; + + if (mode == kSCM_Zero) { + if (x1e4_25_spinnerCanMove) { + const CPlayer& pl = mgr.GetPlayer(); + const CVector3f angVel = pl.GetAngularVelocityOR().getVector(); + float mag = 0.f; + if (angVel.canBeNormalized()) { + mag = angVel.magnitude(); + } + + const float spinImpulse = + (pl.GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed ? + 0.025f * mag : 0.f); if (spinImpulse >= x180_) { SendScriptMsgs(kSS_Play, mgr, kSM_None); + } + + x180_ = spinImpulse; + x138_ += 0.01f * spinImpulse * xfc_float1; + + if (!noBackward) { + x138_ -= f29; + } + } else if (!noBackward) { + x138_ = f28 - twoByDt; + } + } else if (mode == kSCM_One) { + x138_ = (0.01f * x16c_) * xfc_float1 + f28; + + if (!noBackward) { + x138_ -= f29; + + if (std::fabs(x16c_) < dt) { + x16c_ = 0.f; + } else { + x16c_ -= (dt * (x16c_ <= 0.f ? -1.f : 1.f)); + } + } + } + + if (allowWrap) { + x138_ = std::fmod(x138_, 1.f); + if (x138_ < 0.f) { + x138_ += 1.f; + } + } else { + x138_ = zeus::clamp(0.f, x138_, 1.f); + } + + bool r23 = true; + f28 = x138_ - f28; // always 0? + if (zeus::close_enough(x138_, 1.f, FLT_EPSILON)) { + if (!x1e4_27_sfx3Played) { + if (x174_sfx3 != 0xFFFF) { + CSfxManager::AddEmitter(x174_sfx3, GetTranslation(), {}, true, false, 0x7F, + kInvalidAreaId); + } + + x1e4_27_sfx3Played = true; + } + + SendScriptMsgs(kSS_MaxReached, mgr, kSM_None); + r23 = false; + } else { + x1e4_27_sfx3Played = false; + } + + if (zeus::close_enough(x138_, 0.f, FLT_EPSILON)) { + if (!x1e4_26_sfx2Played) { + if (x172_sfx2 != 0xFFFF) { + CSfxManager::AddEmitter(x172_sfx2, GetTranslation(), {}, true, false, 0x7F, + kInvalidAreaId); + } + + x1e4_26_sfx2Played = true; + } + + SendScriptMsgs(kSS_Zero, mgr, kSM_None); + r23 = false; + } else { + x1e4_26_sfx2Played = false; + } + + if (r23) { + if (x170_sfx1 != 0xFFFF) { + x184_.AddValue(0.f <= f28 ? 100 : 0x7f); + const std::optional avg = x184_.GetAverage(); + AddOrUpdateEmitter(0.f <= f28 ? x108_float4 : 1.f, x178_sfxHandle, x170_sfx1, + GetTranslation(), avg.value()); + } + } else { + DeleteEmitter(x178_sfxHandle); + } + + CAnimData* animData = plat->GetModelData()->GetAnimationData(); + const float dur = animData->GetAnimationDuration(animData->GetDefaultAnimation()) * x138_; + animData->SetPhase(0.f); + animData->SetPlaybackRate(1.f); + const SAdvancementDeltas& deltas = plat->UpdateAnimation(dur, mgr, true); + plat->SetTransform(x13c_spinnerInitialXf * + deltas.xc_rotDelta.toTransform(deltas.x0_posDelta)); + } + } + } + */ + } +} + +void CScriptSpecialFunction::ThinkObjectFollowLocator(float, CStateManager& mgr) { + TUniqueId followerAct = kInvalidUniqueId; + TUniqueId followedAct = kInvalidUniqueId; + for (rstl::vector< SConnection >::const_iterator conn = GetConnectionList().begin(); + conn != GetConnectionList().end(); ++conn) { + if (conn->x0_state != kSS_Play || + (conn->x4_msg != kSM_Activate && conn->x4_msg != kSM_Deactivate)) { + continue; + } + + // GetIdListForScript seems very different between Ghidra and Metaforce + // const auto search = mgr.GetIdListForScript(conn->x8_objId); + + rstl::pair< TUniqueId, TUniqueId >* it; + if (const CActor* act = TCastToConstPtr< CActor >(mgr.GetObjectById(it->second))) { + if (conn->x4_msg == kSM_Activate && + (act->HasModelData() && act->GetModelData()->HasAnimData()) && act->GetActive()) { + followedAct = it->second; + } else if (conn->x4_msg == kSM_Deactivate) { + followerAct = it->second; + } + } + } + + if (followerAct == kInvalidUniqueId || followedAct == kInvalidUniqueId) { + return; + } + + const CActor* fromAct = TCastToConstPtr< CActor >(mgr.GetObjectById(followedAct)); + CActor* toAct = TCastToPtr< CActor >(mgr.ObjectById(followerAct)); + toAct->SetTransform(fromAct->GetTransform() * + fromAct->GetScaledLocatorTransform(xec_locatorName)); +} + +void CScriptSpecialFunction::ThinkObjectFollowObject(float, CStateManager& mgr) { + TUniqueId followerAct = kInvalidUniqueId; + TUniqueId followedAct = kInvalidUniqueId; + for (rstl::vector< SConnection >::const_iterator conn = GetConnectionList().begin(); + conn != GetConnectionList().end(); ++conn) { + if (conn->x0_state != kSS_Play || + (conn->x4_msg != kSM_Activate && conn->x4_msg != kSM_Deactivate)) { + continue; + } + + // GetIdListForScript seems very different between Ghidra and Metaforce + // const auto search = mgr.GetIdListForScript(conn->x8_objId); + + rstl::pair< TUniqueId, TUniqueId >* it; + if (const CActor* act = TCastToConstPtr< CActor >(mgr.GetObjectById(it->second))) { + if (conn->x4_msg == kSM_Activate && act->GetActive()) { + followedAct = it->second; + } else if (conn->x4_msg == kSM_Deactivate) { + followerAct = it->second; + } + } + } + + const CActor* followed = TCastToConstPtr< CActor >(mgr.GetObjectById(followedAct)); + CActor* follower = TCastToPtr< CActor >(mgr.ObjectById(followerAct)); + if (followed && follower) { + follower->SetTransform(followed->GetTransform()); + } +} + +void CScriptSpecialFunction::ThinkChaffTarget(float dt, CStateManager& mgr) { + /* + const zeus::CAABox box(5.f - GetTranslation(), 5.f + GetTranslation()); + EntityList nearList; + mgr.BuildNearList(nearList, box, CMaterialFilter::MakeInclude({kMT_Projectile}), nullptr); + auto& filter = mgr.GetCameraFilterPass(7); + + for (const auto& uid : nearList) { + if (const TCastToPtr proj = mgr.ObjectById(uid)) { + if (proj->GetHomingTargetId() == GetUniqueId()) { + proj->Set3d0_26(true); + if (mgr.GetPlayer().GetAreaIdAlways() == GetAreaIdAlways()) { + mgr.GetPlayer().SetHudDisable(x100_float2, 0.5f, 2.5f); + filter.SetFilter(EFilterType::Blend, EFilterShape::Fullscreen, 0.f, zeus::skWhite, + CAssetId()); filter.DisableFilter(0.1f); + } + } + } + } + + x194_ = zeus::max(0.f, x194_ - dt); + if (x194_ != 0.f && mgr.GetPlayer()->GetAreaIdAlways() == GetAreaIdAlways()) { + float intfMag = x104_float3 * (0.5f + ((0.5f + x194_) / xfc_float1)); + if (x194_ < 1.f) { + intfMag *= x194_; + } + + mgr.GetPlayerState()->GetStaticInterference().AddSource(GetUniqueId(), intfMag, .5f); + + if (mgr.GetPlayerState()->GetCurrentVisor() != kPV_Scan) { + mgr.GetPlayer()->AddOrbitDisableSource(mgr, GetUniqueId()); + } else { + mgr.GetPlayer()->RemoveOrbitDisableSource(GetUniqueId()); + } + } + */ +} + +void CScriptSpecialFunction::ThinkActorScale(float dt, CStateManager& mgr) { + const float deltaScale = dt * xfc_float1; + + for (rstl::vector< SConnection >::const_iterator conn = GetConnectionList().begin(); + conn != GetConnectionList().end(); ++conn) { + if (conn->x0_state != kSS_Play || conn->x4_msg != kSM_Activate) { + continue; + } + + if (CActor* act = TCastToPtr< CActor >(mgr.ObjectById(mgr.GetIdForScript(conn->x8_objId)))) { + CModelData* mData = act->ModelData(); + if (mData && (mData->HasAnimData() || mData->HasNormalModel())) { + CVector3f scale = mData->GetScale(); + + if (deltaScale > 0.f) { + scale = CVector3f(rstl::min_val(deltaScale + scale.GetX(), x100_float2), + rstl::min_val(deltaScale + scale.GetY(), x100_float2), + rstl::min_val(deltaScale + scale.GetZ(), x100_float2)); + } else { + scale = CVector3f(rstl::max_val(deltaScale + scale.GetX(), x100_float2), + rstl::max_val(deltaScale + scale.GetY(), x100_float2), + rstl::max_val(deltaScale + scale.GetZ(), x100_float2)); + } + + mData->SetScale(scale); + } + } + } +} + +void CScriptSpecialFunction::ThinkSaveStation(float, CStateManager& mgr) { + if (!x1e5_24_doSave || mgr.GetDeferredStateTransition() == kSMT_SaveGame) { + return; + } + + x1e5_24_doSave = false; + if (mgr.GetInSaveUI()) { + SendScriptMsgs(kSS_MaxReached, mgr, kSM_None); + } else { + SendScriptMsgs(kSS_Zero, mgr, kSM_None); + } +} + +void CScriptSpecialFunction::ThinkRainSimulator(float, CStateManager& mgr) { + if ((float(mgr.GetInputFrameIdx()) / 3600.f) < 0.5f) { + SendScriptMsgs(kSS_MaxReached, mgr, kSM_None); + } else { + SendScriptMsgs(kSS_Zero, mgr, kSM_None); + } +} + +void CScriptSpecialFunction::ThinkAreaDamage(float dt, CStateManager& mgr) { + const CPlayerState& playerState = *mgr.GetPlayerState(); + CPlayer& player = *mgr.Player(); + + /* Make sure we're not currently set to take damage, if so reset our state to be as if we're not + */ + if (x1e4_31_inAreaDamage) { + x1e4_31_inAreaDamage = false; + player.DecrementPhazon(); + SendScriptMsgs(kSS_Exited, mgr, kSM_None); + mgr.SetIsFullThreat(false); + } + return; + + if (!x1e4_31_inAreaDamage) { + if (player.GetAreaIdAlways() != GetAreaIdAlways() || + playerState.GetCurrentSuitRaw() != CPlayerState::kPS_Power) { + return; + } + x1e4_31_inAreaDamage = true; + player.IncrementPhazon(); + SendScriptMsgs(kSS_Entered, mgr, kSM_None); + mgr.SetIsFullThreat(true); + } else if (player.GetAreaIdAlways() != GetAreaIdAlways() || + playerState.GetCurrentSuitRaw() != CPlayerState::kPS_Power) { + x1e4_31_inAreaDamage = false; + player.DecrementPhazon(); + SendScriptMsgs(kSS_Exited, mgr, kSM_None); + mgr.SetIsFullThreat(false); + return; + } + + CMaterialList includeList(kMT_Solid); + CMaterialList excudeList(0); + CMaterialFilter filter(CMaterialFilter::MakeIncludeExclude(includeList, excudeList)); + + CDamageInfo dInfo(CWeaponMode(kWT_Heat), xfc_float1 * dt, 0.f, 0.f); + dInfo.SetNoImmunity(true); + mgr.ApplyDamage(GetUniqueId(), player.GetUniqueId(), GetUniqueId(), dInfo, filter, + CVector3f::Zero()); +} + +void CScriptSpecialFunction::ThinkPlayerInArea(float dt, CStateManager& mgr) { + if (mgr.GetPlayer()->GetAreaIdAlways() == GetAreaIdAlways()) { + if (x1e5_25_playerInArea) { + return; + } + + x1e5_25_playerInArea = true; + SendScriptMsgs(kSS_Entered, mgr, kSM_None); + } else if (x1e5_25_playerInArea) { + x1e5_25_playerInArea = false; + SendScriptMsgs(kSS_Exited, mgr, kSM_None); + } +} + +bool CScriptSpecialFunction::ShouldSkipCinematic(CStateManager& stateMgr) const { + return gpGameState->SystemOptions().GetCinematicState(stateMgr.GetWorld()->IGetWorldAssetId(), + GetEditorId()); +} + +void CScriptSpecialFunction::DeleteEmitter(const CSfxHandle& handle) { + if (!handle) { + return; + } + + CSfxManager::RemoveEmitter(handle); +} + +u32 CScriptSpecialFunction::GetSpecialEnding(const CStateManager& mgr) const { + const u32 rate = (mgr.GetPlayerState()->CalculateItemCollectionRate() * 100) / + mgr.GetPlayerState()->GetTotalPickupCount(); + if (rate < 75) { + return 0; + } + if (rate < 100) { + return 1; + } + return 2; +} + +void CScriptSpecialFunction::AddOrUpdateEmitter(float pitch, CSfxHandle& handle, u16 id, + const CVector3f& pos, uchar vol) { + if (!handle) { + handle = CSfxManager::AddEmitter(id, pos, CVector3f::Zero(), vol, true, true, 0x7f, + kInvalidAreaId.value); + } else { + CSfxManager::UpdateEmitter(handle, pos, CVector3f::Zero(), vol); + CSfxManager::PitchBend(handle, 8192.f * pitch + 8192.f); + } +} + +CScriptSpecialFunction::SRingController::SRingController(TUniqueId uid, float rotateSpeed, + bool reachedTarget) +: x0_id(uid) +, x4_rotateSpeed(rotateSpeed) +, x8_reachedTarget(reachedTarget) +, xc_(CVector3f::Zero()) {}