diff --git a/asm/MetroidPrime/Enemies/CBloodFlower.s b/asm/MetroidPrime/Enemies/CBloodFlower.s index 5438db31..84b146b9 100644 --- a/asm/MetroidPrime/Enemies/CBloodFlower.s +++ b/asm/MetroidPrime/Enemies/CBloodFlower.s @@ -755,7 +755,7 @@ lbl_801191EC: /* 8011929C 001161FC 93 A1 00 48 */ stw r29, 0x48(r1) /* 801192A0 00116200 90 01 00 20 */ stw r0, 0x20(r1) /* 801192A4 00116204 91 61 00 24 */ stw r11, 0x24(r1) -/* 801192A8 00116208 48 02 2C 4D */ bl "__ct__21CTargetableProjectileFRC28TToken<18CWeaponDescription>11EWeaponTypeRC12CTransform4f14EMaterialTypesRC11CDamageInfoRC11CDamageInfo9TUniqueId9TUniqueIdRC28TToken<18CWeaponDescription>9TUniqueIdUi" +/* 801192A8 00116208 48 02 2C 4D */ bl "__ct__21CTargetableProjectileFRC28TToken<18CWeaponDescription>11EWeaponTypeRC12CTransform4f14EMaterialTypesRC11CDamageInfoRC11CDamageInfo9TUniqueId7TAreaId9TUniqueIdRC34TLockedToken<18CWeaponDescription>9TUniqueId17EProjectileAttribRCQ24rstl50optional_object<31TLockedToken<15CGenDescription>>Usb" /* 801192AC 0011620C 7C 77 1B 78 */ mr r23, r3 lbl_801192B0: /* 801192B0 00116210 80 7C 08 4C */ lwz r3, 0x84c(r28) diff --git a/asm/MetroidPrime/Weapons/CTargetableProjectile.s b/asm/MetroidPrime/Weapons/CTargetableProjectile.s index dabf67f8..ea09f9ca 100644 --- a/asm/MetroidPrime/Weapons/CTargetableProjectile.s +++ b/asm/MetroidPrime/Weapons/CTargetableProjectile.s @@ -4,8 +4,8 @@ .balign 8 -.global lbl_803E1800 -lbl_803E1800: +.global __vt__21CTargetableProjectile +__vt__21CTargetableProjectile: # ROM: 0x3DE800 .4byte 0 .4byte 0 @@ -35,7 +35,7 @@ lbl_803E1800: .4byte GetSortingBounds__6CActorCFRC13CStateManager .4byte DoUserAnimEvent__6CActorFR13CStateManagerRC13CInt32POINode14EUserEventTypef .4byte ResolveCollisionWithActor__21CTargetableProjectileFRC14CRayCastResultR6CActorR13CStateManager - .4byte Think__21CTargetableProjectileFfR13CStateManager + .4byte Explode__21CTargetableProjectileFRC9CVector3fRC9CVector3f29EWeaponCollisionResponseTypesR13CStateManagerRC20CDamageVulnerability9TUniqueId .4byte 0 .section .sbss @@ -61,9 +61,9 @@ __dt__21CTargetableProjectileFv: /* 8013B890 001387F0 93 C1 00 08 */ stw r30, 8(r1) /* 8013B894 001387F4 7C 7E 1B 79 */ or. r30, r3, r3 /* 8013B898 001387F8 41 82 00 40 */ beq lbl_8013B8D8 -/* 8013B89C 001387FC 3C 60 80 3E */ lis r3, lbl_803E1800@ha +/* 8013B89C 001387FC 3C 60 80 3E */ lis r3, __vt__21CTargetableProjectile@ha /* 8013B8A0 00138800 34 1E 03 D8 */ addic. r0, r30, 0x3d8 -/* 8013B8A4 00138804 38 03 18 00 */ addi r0, r3, lbl_803E1800@l +/* 8013B8A4 00138804 38 03 18 00 */ addi r0, r3, __vt__21CTargetableProjectile@l /* 8013B8A8 00138808 90 1E 00 00 */ stw r0, 0(r30) /* 8013B8AC 0013880C 41 82 00 10 */ beq lbl_8013B8BC /* 8013B8B0 00138810 38 7E 03 D8 */ addi r3, r30, 0x3d8 @@ -259,7 +259,7 @@ lbl_8013BB3C: /* 8013BB68 00138AC8 EF 43 00 72 */ fmuls f26, f3, f1 /* 8013BB6C 00138ACC 7F E3 FB 78 */ mr r3, r31 /* 8013BB70 00138AD0 EF 63 00 32 */ fmuls f27, f3, f0 -/* 8013BB74 00138AD4 48 17 35 9D */ bl sub_802af110 +/* 8013BB74 00138AD4 48 17 35 9D */ bl GetGravity__17CProjectileWeaponCFv /* 8013BB78 00138AD8 C1 0D A3 C8 */ lfs f8, lbl_805A8F88@sda21(r13) /* 8013BB7C 00138ADC EC 1C 06 72 */ fmuls f0, f28, f25 /* 8013BB80 00138AE0 C0 63 00 00 */ lfs f3, 0(r3) @@ -311,8 +311,8 @@ lbl_8013BB3C: /* 8013BC38 00138B98 38 21 00 90 */ addi r1, r1, 0x90 /* 8013BC3C 00138B9C 4E 80 00 20 */ blr -.global Think__21CTargetableProjectileFfR13CStateManager -Think__21CTargetableProjectileFfR13CStateManager: +.global Explode__21CTargetableProjectileFRC9CVector3fRC9CVector3f29EWeaponCollisionResponseTypesR13CStateManagerRC20CDamageVulnerability9TUniqueId +Explode__21CTargetableProjectileFRC9CVector3fRC9CVector3f29EWeaponCollisionResponseTypesR13CStateManagerRC20CDamageVulnerability9TUniqueId: /* 8013BC40 00138BA0 94 21 FE F0 */ stwu r1, -0x110(r1) /* 8013BC44 00138BA4 7C 08 02 A6 */ mflr r0 /* 8013BC48 00138BA8 90 01 01 14 */ stw r0, 0x114(r1) @@ -494,8 +494,8 @@ Accept__21CTargetableProjectileFR8IVisitor: /* 8013BEEC 00138E4C 38 21 00 10 */ addi r1, r1, 0x10 /* 8013BEF0 00138E50 4E 80 00 20 */ blr -.global "__ct__21CTargetableProjectileFRC28TToken<18CWeaponDescription>11EWeaponTypeRC12CTransform4f14EMaterialTypesRC11CDamageInfoRC11CDamageInfo9TUniqueId9TUniqueIdRC28TToken<18CWeaponDescription>9TUniqueIdUi" -"__ct__21CTargetableProjectileFRC28TToken<18CWeaponDescription>11EWeaponTypeRC12CTransform4f14EMaterialTypesRC11CDamageInfoRC11CDamageInfo9TUniqueId9TUniqueIdRC28TToken<18CWeaponDescription>9TUniqueIdUi": +.global "__ct__21CTargetableProjectileFRC28TToken<18CWeaponDescription>11EWeaponTypeRC12CTransform4f14EMaterialTypesRC11CDamageInfoRC11CDamageInfo9TUniqueId7TAreaId9TUniqueIdRC34TLockedToken<18CWeaponDescription>9TUniqueId17EProjectileAttribRCQ24rstl50optional_object<31TLockedToken<15CGenDescription>>Usb" +"__ct__21CTargetableProjectileFRC28TToken<18CWeaponDescription>11EWeaponTypeRC12CTransform4f14EMaterialTypesRC11CDamageInfoRC11CDamageInfo9TUniqueId7TAreaId9TUniqueIdRC34TLockedToken<18CWeaponDescription>9TUniqueId17EProjectileAttribRCQ24rstl50optional_object<31TLockedToken<15CGenDescription>>Usb": /* 8013BEF4 00138E54 94 21 FF 80 */ stwu r1, -0x80(r1) /* 8013BEF8 00138E58 7C 08 02 A6 */ mflr r0 /* 8013BEFC 00138E5C 7C EC 3B 78 */ mr r12, r7 @@ -549,9 +549,9 @@ Accept__21CTargetableProjectileFR8IVisitor: /* 8013BFBC 00138F1C 90 01 00 24 */ stw r0, 0x24(r1) /* 8013BFC0 00138F20 93 A1 00 28 */ stw r29, 0x28(r1) /* 8013BFC4 00138F24 48 0D 96 D5 */ bl "__ct__17CEnergyProjectileFbRC28TToken<18CWeaponDescription>11EWeaponTypeRC12CTransform4f14EMaterialTypesRC11CDamageInfo9TUniqueId7TAreaId9TUniqueId9TUniqueIdUibRC9CVector3fRCQ24rstl50optional_object<31TLockedToken<15CGenDescription>>Usb" -/* 8013BFC8 00138F28 3C 60 80 3E */ lis r3, lbl_803E1800@ha +/* 8013BFC8 00138F28 3C 60 80 3E */ lis r3, __vt__21CTargetableProjectile@ha /* 8013BFCC 00138F2C 7F C4 F3 78 */ mr r4, r30 -/* 8013BFD0 00138F30 38 03 18 00 */ addi r0, r3, lbl_803E1800@l +/* 8013BFD0 00138F30 38 03 18 00 */ addi r0, r3, __vt__21CTargetableProjectile@l /* 8013BFD4 00138F34 38 7C 03 D8 */ addi r3, r28, 0x3d8 /* 8013BFD8 00138F38 90 1C 00 00 */ stw r0, 0(r28) /* 8013BFDC 00138F3C 48 20 4E CD */ bl __ct__6CTokenFRC6CToken diff --git a/asm/Weapons/CProjectileWeapon.s b/asm/Weapons/CProjectileWeapon.s index fc78f526..d42260bc 100644 --- a/asm/Weapons/CProjectileWeapon.s +++ b/asm/Weapons/CProjectileWeapon.s @@ -319,8 +319,8 @@ SetGlobalSeed__17CProjectileWeaponFUs: /* 802AF108 002AC068 90 6D 9A 88 */ stw r3, lbl_805A8648@sda21(r13) /* 802AF10C 002AC06C 4E 80 00 20 */ blr -.global sub_802af110 -sub_802af110: +.global GetGravity__17CProjectileWeaponCFv +GetGravity__17CProjectileWeaponCFv: /* 802AF110 002AC070 38 63 00 BC */ addi r3, r3, 0xbc /* 802AF114 002AC074 4E 80 00 20 */ blr diff --git a/configure.py b/configure.py index 81702c79..99edf770 100755 --- a/configure.py +++ b/configure.py @@ -195,7 +195,7 @@ LIBS = [ "MetroidPrime/BodyState/CBSTurn", "MetroidPrime/BodyState/CBodyController", "MetroidPrime/BodyState/CBSLoopAttack", - "MetroidPrime/Weapons/CTargetableProjectile", + ["MetroidPrime/Weapons/CTargetableProjectile", False], "MetroidPrime/BodyState/CBSLoopReaction", "MetroidPrime/CSteeringBehaviors", ["MetroidPrime/BodyState/CBSGroundHit", False], diff --git a/include/Collision/CMaterialList.hpp b/include/Collision/CMaterialList.hpp index 67e0bc7b..7acf7268 100644 --- a/include/Collision/CMaterialList.hpp +++ b/include/Collision/CMaterialList.hpp @@ -72,7 +72,7 @@ static EMaterialTypes SolidMaterial = kMT_Solid; class CMaterialList { public: CMaterialList() : value(0) {} - CMaterialList(const EMaterialTypes& m1) : value(0) { Add(m1); } + explicit CMaterialList(const EMaterialTypes& m1) : value(0) { Add(m1); } CMaterialList(const EMaterialTypes& m1, const EMaterialTypes& m2) : value(0) { Add(m1); Add(m2); @@ -100,7 +100,7 @@ public: Add(m4); Add(m5); } - CMaterialList(u64 value) : value(value) {} + explicit CMaterialList(u64 value) : value(value) {} void Add(EMaterialTypes material) { value |= u64(1) << material; } void Add(const CMaterialList& material) { value |= material.value; } diff --git a/include/MetroidPrime/Player/CPlayer.hpp b/include/MetroidPrime/Player/CPlayer.hpp index b8a26504..ec3f213b 100644 --- a/include/MetroidPrime/Player/CPlayer.hpp +++ b/include/MetroidPrime/Player/CPlayer.hpp @@ -192,8 +192,10 @@ public: void IncrementPhazon(); void DecrementPhazon(); // GetMovementDirection2D__7CPlayerCFv ?? + void SetOrbitTargetId(TUniqueId id, CStateManager& mgr); void AddOrbitDisableSource(CStateManager& mgr, TUniqueId addId); void RemoveOrbitDisableSource(TUniqueId uid); + void ResetAimTargetPrediction(TUniqueId target); void ApplySubmergedPitchBend(CSfxHandle& sfx); diff --git a/include/MetroidPrime/Weapons/CGameProjectile.hpp b/include/MetroidPrime/Weapons/CGameProjectile.hpp index 13a3a1f0..1b42d3ed 100644 --- a/include/MetroidPrime/Weapons/CGameProjectile.hpp +++ b/include/MetroidPrime/Weapons/CGameProjectile.hpp @@ -34,6 +34,10 @@ public: const CVector3f& GetPreviousPos() const { return x298_previousPos; } TUniqueId GetHomingTargetId() const { return x2c0_homingTargetId; } + TUniqueId GetHitProjectileOwner() const { return x2c4_hitProjectileOwner; } + void SetHitProjectileOwner(TUniqueId id) { x2c4_hitProjectileOwner = id; } + + bool GetWeaponActive() const { return x2e4_24_active; } protected: rstl::optional_object< TLockedToken< CGenDescription > > x158_visorParticle; diff --git a/include/MetroidPrime/Weapons/CProjectileWeapon.hpp b/include/MetroidPrime/Weapons/CProjectileWeapon.hpp index 9278527f..1c8f6568 100644 --- a/include/MetroidPrime/Weapons/CProjectileWeapon.hpp +++ b/include/MetroidPrime/Weapons/CProjectileWeapon.hpp @@ -28,6 +28,8 @@ public: virtual CVector3f GetTranslation() const; virtual CTransform4f GetTransform() const; + const CVector3f& GetVelocity() const; // { return xb0_velocity; } + CVector3f GetGravity() const; // { return xbc_gravity; } static float GetTickPeriod(); // { return 0.0166667f; } private: diff --git a/include/MetroidPrime/Weapons/CTargetableProjectile.hpp b/include/MetroidPrime/Weapons/CTargetableProjectile.hpp new file mode 100644 index 00000000..06c7f760 --- /dev/null +++ b/include/MetroidPrime/Weapons/CTargetableProjectile.hpp @@ -0,0 +1,29 @@ +#ifndef _CTARGETABLEPROJECTILE +#define _CTARGETABLEPROJECTILE + +#include "MetroidPrime/Weapons/CEnergyProjectile.hpp" + +class CTargetableProjectile : public CEnergyProjectile { +public: + CTargetableProjectile( + const TToken< CWeaponDescription >& desc, EWeaponType type, const CTransform4f& xf, + EMaterialTypes materials, const CDamageInfo& damage, const CDamageInfo& damage2, + TUniqueId uid, TAreaId aid, TUniqueId owner, + const TLockedToken< CWeaponDescription >& weapDesc, TUniqueId homingTarget, + EProjectileAttrib attribs, + const rstl::optional_object< TLockedToken< CGenDescription > >& visorParticle, ushort visorSfx, + bool sendCollideMsg); + + void Accept(IVisitor&) override; + CVector3f GetAimPosition(const CStateManager&, float) const override; + bool Explode(const CVector3f& pos, const CVector3f& normal, EWeaponCollisionResponseTypes type, + CStateManager& mgr, const CDamageVulnerability& dVuln, TUniqueId hitActor) override; + void ResolveCollisionWithActor(const CRayCastResult& res, CActor& act, + CStateManager& mgr) override; + +private: + TToken< CWeaponDescription > x3d8_weaponDesc; + CDamageInfo x3e0_damage; +}; + +#endif // _CTARGETABLEPROJECTILE diff --git a/src/MetroidPrime/Weapons/CTargetableProjectile.cpp b/src/MetroidPrime/Weapons/CTargetableProjectile.cpp new file mode 100644 index 00000000..d51d41be --- /dev/null +++ b/src/MetroidPrime/Weapons/CTargetableProjectile.cpp @@ -0,0 +1,77 @@ +#include "MetroidPrime/Weapons/CTargetableProjectile.hpp" + +#include "MetroidPrime/Player/CPlayer.hpp" + +#include "Kyoto/Audio/CSfxManager.hpp" + +CTargetableProjectile::CTargetableProjectile( + const TToken< CWeaponDescription >& desc, EWeaponType type, const CTransform4f& xf, + EMaterialTypes materials, const CDamageInfo& damage, const CDamageInfo& damage2, TUniqueId uid, + TAreaId aid, TUniqueId owner, const TLockedToken< CWeaponDescription >& weapDesc, + TUniqueId homingTarget, EProjectileAttrib attribs, + const rstl::optional_object< TLockedToken< CGenDescription > >& visorParticle, ushort visorSfx, + bool sendCollideMsg) +: CEnergyProjectile(true, desc, type, xf, materials, damage, uid, aid, owner, homingTarget, + attribs | kPA_BigProjectile | kPA_PartialCharge | kPA_PlasmaProjectile, false, + CVector3f(1.f, 1.f, 1.f), visorParticle, visorSfx, sendCollideMsg) +, x3d8_weaponDesc(weapDesc) +, x3e0_damage(damage2) { + MaterialList().Add(kMT_Target); + MaterialList().Add(kMT_Orbit); +} + +void CTargetableProjectile::Accept(IVisitor& visitor) { visitor.Visit(*this); } + +bool CTargetableProjectile::Explode(const CVector3f& pos, const CVector3f& normal, + EWeaponCollisionResponseTypes type, CStateManager& mgr, + const CDamageVulnerability& dVuln, TUniqueId hitActor) { + bool ret = CEnergyProjectile::Explode(pos, normal, type, mgr, dVuln, hitActor); + + if (!GetWeaponActive()) { + if (GetHitProjectileOwner() != kInvalidUniqueId && + GetHitProjectileOwner() == mgr.GetPlayer()->GetUniqueId()) { + + if (const CActor* act = TCastToConstPtr< CActor >(mgr.GetObjectById(GetOwnerId()))) { + TUniqueId uid = mgr.AllocateUniqueId(); + CVector3f aimPosition = act->GetAimPosition(mgr, 0.f); + + CEnergyProjectile* projectile = new CEnergyProjectile( + true, x3d8_weaponDesc, GetWeaponType(), + CTransform4f::LookAt(x170_projectile.GetTranslation(), aimPosition, CVector3f::Up()), + kMT_Player, x3e0_damage, uid, GetCurrentAreaId(), GetHitProjectileOwner(), GetOwnerId(), + kPA_None, false, CVector3f(1.f, 1.f, 1.f), rstl::optional_object_null(), + CSfxManager::kInternalInvalidSfxId, false); + mgr.AddObject(projectile); + projectile->AddMaterial(kMT_Orbit, mgr); + mgr.Player()->ResetAimTargetPrediction(uid); + mgr.Player()->SetOrbitTargetId(uid, mgr); + SetHitProjectileOwner(kInvalidUniqueId); + } + } + } + + return ret; +} + +CVector3f CTargetableProjectile::GetAimPosition(const CStateManager& mgr, float dt) const { + static float tickRecip = 1.f / CProjectileWeapon::GetTickPeriod(); + + // CVector3f translation = GetTranslation(); + // CVector3f velocity = tickRecip * x170_projectile.GetVelocity(); + // CVector3f gravity = (tickRecip * x170_projectile.GetGravity()) * 0.5f; + + // return (dt * dt * gravity) + (dt * velocity) + translation; + + return (dt * dt * ((tickRecip * x170_projectile.GetGravity()) * 0.5f)) + + (dt * (tickRecip * x170_projectile.GetVelocity())) + GetTranslation(); +} + +void CTargetableProjectile::ResolveCollisionWithActor(const CRayCastResult& res, CActor& act, + CStateManager& mgr) { + + CVector3f aimPosition = GetAimPosition(mgr, 0.1f); + CTransform4f xf = CTransform4f::LookAt(GetTranslation(), aimPosition); + xf.SetTranslation(GetTranslation()); + SetTransform(xf); + CEnergyProjectile::ResolveCollisionWithActor(res, act, mgr); +}