diff --git a/asm/MetroidPrime/Enemies/CRipper.s b/asm/MetroidPrime/Enemies/CRipper.s index 37d263d8..0820c62c 100644 --- a/asm/MetroidPrime/Enemies/CRipper.s +++ b/asm/MetroidPrime/Enemies/CRipper.s @@ -321,7 +321,7 @@ AddPlatform__7CRipperFR13CStateManager: /* 8015BF5C 00158EBC 3B 60 00 01 */ li r27, 1 /* 8015BF60 00158EC0 B1 61 00 10 */ sth r11, 0x10(r1) /* 8015BF64 00158EC4 90 01 00 08 */ stw r0, 8(r1) -/* 8015BF68 00158EC8 48 0D 6C 31 */ bl "__ct__25CRipperControlledPlatformF9TUniqueId9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fRC6CAABoxbRCQ24rstl58optional_object<39TLockedToken<23CCollidableOBBTreeGroup>>" +/* 8015BF68 00158EC8 48 0D 6C 31 */ bl "__ct__25CRipperControlledPlatformF9TUniqueId9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fRC6CAABoxbRCQ24rstl67optional_object<48TLockedToken<32CCollidableOBBTreeGroupContainer>>" /* 8015BF6C 00158ECC 7C 7F 1B 78 */ mr r31, r3 lbl_8015BF70: /* 8015BF70 00158ED0 7F 60 07 75 */ extsb. r0, r27 diff --git a/asm/MetroidPrime/Enemies/CRipperControlledPlatform.s b/asm/MetroidPrime/Enemies/CRipperControlledPlatform.s index 5d26f97c..ee2d6f1b 100644 --- a/asm/MetroidPrime/Enemies/CRipperControlledPlatform.s +++ b/asm/MetroidPrime/Enemies/CRipperControlledPlatform.s @@ -3,8 +3,8 @@ .section .data .balign 8 -.global lbl_803E80C0 -lbl_803E80C0: +.global __vt__25CRipperControlledPlatform +__vt__25CRipperControlledPlatform: # ROM: 0x3E50C0 .4byte 0 .4byte 0 @@ -40,7 +40,7 @@ lbl_803E80C0: .4byte GetStepUpHeight__13CPhysicsActorCFv .4byte GetWeight__13CPhysicsActorCFv .4byte SplashThink__15CScriptPlatformCFRC6CAABoxRC11CFluidPlanefR13CStateManager - .4byte Move__25CRipperControlledPlatformFR13CStateManager + .4byte Move__25CRipperControlledPlatformFfR13CStateManager .4byte 0 .section .text, "ax" @@ -55,9 +55,9 @@ __dt__25CRipperControlledPlatformFv: /* 802327D4 0022F734 93 C1 00 08 */ stw r30, 8(r1) /* 802327D8 0022F738 7C 7E 1B 79 */ or. r30, r3, r3 /* 802327DC 0022F73C 41 82 00 28 */ beq lbl_80232804 -/* 802327E0 0022F740 3C A0 80 3F */ lis r5, lbl_803E80C0@ha +/* 802327E0 0022F740 3C A0 80 3F */ lis r5, __vt__25CRipperControlledPlatform@ha /* 802327E4 0022F744 38 80 00 00 */ li r4, 0 -/* 802327E8 0022F748 38 05 80 C0 */ addi r0, r5, lbl_803E80C0@l +/* 802327E8 0022F748 38 05 80 C0 */ addi r0, r5, __vt__25CRipperControlledPlatform@l /* 802327EC 0022F74C 90 1E 00 00 */ stw r0, 0(r30) /* 802327F0 0022F750 4B E8 14 1D */ bl __dt__15CScriptPlatformFv /* 802327F4 0022F754 7F E0 07 35 */ extsh. r0, r31 @@ -73,8 +73,8 @@ lbl_80232804: /* 80232818 0022F778 38 21 00 10 */ addi r1, r1, 0x10 /* 8023281C 0022F77C 4E 80 00 20 */ blr -.global Move__25CRipperControlledPlatformFR13CStateManager -Move__25CRipperControlledPlatformFR13CStateManager: +.global Move__25CRipperControlledPlatformFfR13CStateManager +Move__25CRipperControlledPlatformFfR13CStateManager: /* 80232820 0022F780 94 21 EF 40 */ stwu r1, -0x10c0(r1) /* 80232824 0022F784 7C 08 02 A6 */ mflr r0 /* 80232828 0022F788 90 01 10 C4 */ stw r0, 0x10c4(r1) @@ -314,8 +314,8 @@ lbl_80232B78: /* 80232B90 0022FAF0 38 21 10 C0 */ addi r1, r1, 0x10c0 /* 80232B94 0022FAF4 4E 80 00 20 */ blr -.global "__ct__25CRipperControlledPlatformF9TUniqueId9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fRC6CAABoxbRCQ24rstl58optional_object<39TLockedToken<23CCollidableOBBTreeGroup>>" -"__ct__25CRipperControlledPlatformF9TUniqueId9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fRC6CAABoxbRCQ24rstl58optional_object<39TLockedToken<23CCollidableOBBTreeGroup>>": +.global "__ct__25CRipperControlledPlatformF9TUniqueId9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fRC6CAABoxbRCQ24rstl67optional_object<48TLockedToken<32CCollidableOBBTreeGroupContainer>>" +"__ct__25CRipperControlledPlatformF9TUniqueId9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fRC6CAABoxbRCQ24rstl67optional_object<48TLockedToken<32CCollidableOBBTreeGroupContainer>>": /* 80232B98 0022FAF8 94 21 FE F0 */ stwu r1, -0x110(r1) /* 80232B9C 0022FAFC 7C 08 02 A6 */ mflr r0 /* 80232BA0 0022FB00 90 01 01 14 */ stw r0, 0x114(r1) @@ -369,9 +369,9 @@ lbl_80232B78: /* 80232C60 0022FBC0 38 61 00 9C */ addi r3, r1, 0x9c /* 80232C64 0022FBC4 38 80 FF FF */ li r4, -1 /* 80232C68 0022FBC8 4B EE 3D E5 */ bl __dt__10CModelDataFv -/* 80232C6C 0022FBCC 3C 80 80 3F */ lis r4, lbl_803E80C0@ha +/* 80232C6C 0022FBCC 3C 80 80 3F */ lis r4, __vt__25CRipperControlledPlatform@ha /* 80232C70 0022FBD0 7F E3 FB 78 */ mr r3, r31 -/* 80232C74 0022FBD4 38 04 80 C0 */ addi r0, r4, lbl_803E80C0@l +/* 80232C74 0022FBD4 38 04 80 C0 */ addi r0, r4, __vt__25CRipperControlledPlatform@l /* 80232C78 0022FBD8 90 1F 00 00 */ stw r0, 0(r31) /* 80232C7C 0022FBDC A0 17 00 00 */ lhz r0, 0(r23) /* 80232C80 0022FBE0 B0 1F 03 58 */ sth r0, 0x358(r31) diff --git a/configure.py b/configure.py index 89032759..0c280ad5 100755 --- a/configure.py +++ b/configure.py @@ -332,7 +332,7 @@ LIBS = [ "MetroidPrime/Enemies/CBouncyGrenade", "MetroidPrime/Enemies/CGrenadeLauncher", "MetroidPrime/Weapons/CShockWave", - "MetroidPrime/Enemies/CRipperControlledPlatform", + ["MetroidPrime/Enemies/CRipperControlledPlatform", True], "MetroidPrime/Enemies/CKnockBackController", ["MetroidPrime/Player/CWorldLayerState", False], "MetroidPrime/Enemies/CMagdolite", diff --git a/include/MetroidPrime/CActor.hpp b/include/MetroidPrime/CActor.hpp index 38df7fe1..28608806 100644 --- a/include/MetroidPrime/CActor.hpp +++ b/include/MetroidPrime/CActor.hpp @@ -272,6 +272,7 @@ public: void SetTranslation(const CVector3f& vec); CTransform4f GetLocatorTransform(const rstl::string& segName) const; CTransform4f GetScaledLocatorTransform(const rstl::string& segName) const; + float GetYaw() const; /// ???? bool NullModel() const { return !GetAnimationData() && !GetModelData()->HasNormalModel(); } diff --git a/include/MetroidPrime/CGameCollision.hpp b/include/MetroidPrime/CGameCollision.hpp index 2111371b..db99bd4a 100644 --- a/include/MetroidPrime/CGameCollision.hpp +++ b/include/MetroidPrime/CGameCollision.hpp @@ -28,6 +28,8 @@ public: TUniqueId&, CCollisionInfo&, double&); static CRayCastResult RayStaticIntersection(const CStateManager&, const CVector3f&, const CVector3f&, float, const CMaterialFilter&); + + static void Move(CStateManager& mgr, CPhysicsActor& actor, float dt, const TEntityList*); }; #endif // _CGAMECOLLISION diff --git a/include/MetroidPrime/Enemies/CRipperControlledPlatform.hpp b/include/MetroidPrime/Enemies/CRipperControlledPlatform.hpp new file mode 100644 index 00000000..8f05e978 --- /dev/null +++ b/include/MetroidPrime/Enemies/CRipperControlledPlatform.hpp @@ -0,0 +1,21 @@ +#ifndef _CRIPPERCONTROLLEDPLATFORM +#define _CRIPPERCONTROLLEDPLATFORM + +#include "MetroidPrime/ScriptObjects/CScriptPlatform.hpp" + +class CRipperControlledPlatform : public CScriptPlatform { + +public: + CRipperControlledPlatform( + TUniqueId, TUniqueId, const rstl::string&, const CEntityInfo&, const CTransform4f&, + const CAABox&, bool, const rstl::optional_object< TLockedToken< CCollidableOBBTreeGroupContainer > >&); + ~CRipperControlledPlatform(); + + CQuaternion Move(float, CStateManager&) override; + +private: + TUniqueId x358_owner; + float x35c_yaw; +}; + +#endif // _CRIPPERCONTROLLEDPLATFORM diff --git a/include/MetroidPrime/ScriptObjects/CScriptPlatform.hpp b/include/MetroidPrime/ScriptObjects/CScriptPlatform.hpp index 5f82e687..842e30e2 100644 --- a/include/MetroidPrime/ScriptObjects/CScriptPlatform.hpp +++ b/include/MetroidPrime/ScriptObjects/CScriptPlatform.hpp @@ -67,6 +67,9 @@ public: TUniqueId GetWaypoint(CStateManager& mgr); TUniqueId GetNext(TUniqueId uid, CStateManager& mgr); + bool IsRider(TUniqueId id) const; + bool IsSlave(TUniqueId id) const; + void SetControlledAnimation(bool controlled) { x356_25_controlledAnimation = controlled; } static void AddRider(rstl::vector< SRiders >& riders, TUniqueId riderId, diff --git a/obj_files.mk b/obj_files.mk index ee5da86b..b8cb7888 100644 --- a/obj_files.mk +++ b/obj_files.mk @@ -297,7 +297,7 @@ METROIDPRIME :=\ $(BUILD_DIR)/asm/MetroidPrime/Enemies/CBouncyGrenade.o\ $(BUILD_DIR)/asm/MetroidPrime/Enemies/CGrenadeLauncher.o\ $(BUILD_DIR)/asm/MetroidPrime/Weapons/CShockWave.o\ - $(BUILD_DIR)/asm/MetroidPrime/Enemies/CRipperControlledPlatform.o\ + $(BUILD_DIR)/src/MetroidPrime/Enemies/CRipperControlledPlatform.o\ $(BUILD_DIR)/asm/MetroidPrime/Enemies/CKnockBackController.o\ $(BUILD_DIR)/asm/MetroidPrime/Player/CWorldLayerState.o\ $(BUILD_DIR)/asm/MetroidPrime/Enemies/CMagdolite.o\ diff --git a/src/MetroidPrime/Enemies/CRipperControlledPlatform.cpp b/src/MetroidPrime/Enemies/CRipperControlledPlatform.cpp new file mode 100644 index 00000000..911ba605 --- /dev/null +++ b/src/MetroidPrime/Enemies/CRipperControlledPlatform.cpp @@ -0,0 +1,52 @@ +#include "MetroidPrime/Enemies/CRipperControlledPlatform.hpp" + +#include "MetroidPrime/CActorParameters.hpp" +#include "MetroidPrime/CGameCollision.hpp" + +#include "Kyoto/Math/CRelAngle.hpp" + +CRipperControlledPlatform::CRipperControlledPlatform( + TUniqueId uid, TUniqueId owner, const rstl::string& name, const CEntityInfo& info, + const CTransform4f& xf, const CAABox& bounds, bool active, + const rstl::optional_object< TLockedToken< CCollidableOBBTreeGroupContainer > >& colTree) +: CScriptPlatform(uid, name, info, xf, CModelData::CModelDataNull(), CActorParameters::None(), + bounds, 0.f, false, 1.f, active, CHealthInfo(FLT_MAX, 10.f), + CDamageVulnerability::ImmuneVulnerabilty(), colTree, false, 1, 1) +, x358_owner(owner) +, x35c_yaw(GetYaw()) {} + +float RCP_2PI = 0.15915494f; + +CQuaternion CRipperControlledPlatform::Move(float arg, CStateManager& mgr) { + if (const CActor* actor = static_cast< CActor* >(mgr.ObjectById(x358_owner))) { + CVector3f delta = actor->GetTranslation() - GetTranslation(); + MoveToWR(GetTranslation() + delta, arg); + + float zRot = CMath::ClampRadians(actor->GetYaw() - x35c_yaw); + if (zRot > M_PIF) { + zRot -= M_2PIF; + } + const CQuaternion quat = CQuaternion::ZRotation(CRelAngle::FromRadians(zRot)); + RotateToOR(quat, arg); + + TEntityList nearList; + CAABox volume(GetMotionVolume(arg)); + mgr.BuildColliderList(nearList, *this, volume); + + TEntityList filteredNearList; + for (TEntityList::iterator id = nearList.begin(); id != nearList.end(); ++id) { + if (!IsRider(*id) && !IsSlave(*id)) { + filteredNearList.push_back(*id); + } + } + + SetMovable(true); + CGameCollision::Move(mgr, *this, arg, &filteredNearList); + SetMovable(false); + x35c_yaw = GetYaw(); + return quat; + } + return CQuaternion::NoRotation(); +} + +CRipperControlledPlatform::~CRipperControlledPlatform() {}