Add CElectricBeamProjectile

This commit is contained in:
Henrique Gemignani Passos Lima 2022-11-24 01:49:52 +02:00
parent 29457d953c
commit 24390b8901
No known key found for this signature in database
GPG Key ID: E224F951761145F8
10 changed files with 223 additions and 27 deletions

View File

@ -990,7 +990,7 @@ lbl_80251538:
/* 802515A8 0024E508 91 61 00 0C */ stw r11, 0xc(r1)
/* 802515AC 0024E50C 93 41 00 2C */ stw r26, 0x2c(r1)
/* 802515B0 0024E510 90 01 00 10 */ stw r0, 0x10(r1)
/* 802515B4 0024E514 48 00 0D 89 */ bl __ct__23CElectricBeamProjectile
/* 802515B4 0024E514 48 00 0D 89 */ bl "__ct__23CElectricBeamProjectileFRC28TToken<18CWeaponDescription>11EWeaponTypeRC17SElectricBeamInfoRC12CTransform4f14EMaterialTypesRC11CDamageInfo9TUniqueId7TAreaId9TUniqueId17EProjectileAttrib"
/* 802515B8 0024E518 7C 64 1B 78 */ mr r4, r3
lbl_802515BC:
/* 802515BC 0024E51C 7F A3 EB 78 */ mr r3, r29

View File

@ -513,8 +513,8 @@ lbl_80199484:
/* 80199484 001963E4 38 21 00 20 */ addi r1, r1, 0x20
/* 80199488 001963E8 4E 80 00 20 */ blr
.global "__ct__15CBeamProjectileFRC28TToken<18CWeaponDescription>RCQ24rstl66basic_string<c,Q24rstl14char_traits<c>,Q24rstl17rmemory_allocator>11EWeaponTypeRC12CTransform4fiff14EMaterialTypesRC11CDamageInfo9TUniqueId9TUniqueIdUib"
"__ct__15CBeamProjectileFRC28TToken<18CWeaponDescription>RCQ24rstl66basic_string<c,Q24rstl14char_traits<c>,Q24rstl17rmemory_allocator>11EWeaponTypeRC12CTransform4fiff14EMaterialTypesRC11CDamageInfo9TUniqueId9TUniqueIdUib":
.global "__ct__15CBeamProjectileFRC28TToken<18CWeaponDescription>RCQ24rstl66basic_string<c,Q24rstl14char_traits<c>,Q24rstl17rmemory_allocator>11EWeaponTypeRC12CTransform4fiff14EMaterialTypesRC11CDamageInfo9TUniqueId7TAreaId9TUniqueId17EProjectileAttribb"
"__ct__15CBeamProjectileFRC28TToken<18CWeaponDescription>RCQ24rstl66basic_string<c,Q24rstl14char_traits<c>,Q24rstl17rmemory_allocator>11EWeaponTypeRC12CTransform4fiff14EMaterialTypesRC11CDamageInfo9TUniqueId7TAreaId9TUniqueId17EProjectileAttribb":
/* 8019948C 001963EC 94 21 FF 40 */ stwu r1, -0xc0(r1)
/* 80199490 001963F0 7C 08 02 A6 */ mflr r0
/* 80199494 001963F4 90 01 00 C4 */ stw r0, 0xc4(r1)

View File

@ -3,8 +3,8 @@
.section .data
.balign 8
.global lbl_803E9118
lbl_803E9118:
.global __vt__23CElectricBeamProjectile
__vt__23CElectricBeamProjectile:
# ROM: 0x3E6118
.4byte 0
.4byte 0
@ -23,7 +23,7 @@ lbl_803E9118:
.4byte GetDamageVulnerability__6CActorCFv
.4byte GetDamageVulnerability__6CActorCFRC9CVector3fRC9CVector3fRC11CDamageInfo
.4byte GetTouchBounds__15CBeamProjectileCFv
.4byte nullsub_65
.4byte Touch__23CElectricBeamProjectileFR6CActorR13CStateManager
.4byte GetOrbitPosition__6CActorCFRC13CStateManager
.4byte GetAimPosition__6CActorCFRC13CStateManagerf
.4byte GetHomingPosition__6CActorCFRC13CStateManagerf
@ -34,9 +34,9 @@ lbl_803E9118:
.4byte GetSortingBounds__6CActorCFRC13CStateManager
.4byte DoUserAnimEvent__6CActorFR13CStateManagerRC13CInt32POINode14EUserEventTypef
.4byte ResolveCollisionWithActor__15CGameProjectileFRC14CRayCastResultR6CActorR13CStateManager
.4byte sub_80251e84
.4byte sub_80251d38
.4byte sub_80251dd4
.4byte UpdateFx__23CElectricBeamProjectileFRC12CTransform4ffR13CStateManager
.4byte ResetBeam__23CElectricBeamProjectileFR13CStateManagerb
.4byte Fire__23CElectricBeamProjectileFRC12CTransform4fR13CStateManagerb
.4byte 0
.section .sdata
@ -60,9 +60,9 @@ __dt__23CElectricBeamProjectileFv:
/* 80251BC4 0024EB24 93 C1 00 08 */ stw r30, 8(r1)
/* 80251BC8 0024EB28 7C 7E 1B 79 */ or. r30, r3, r3
/* 80251BCC 0024EB2C 41 82 00 98 */ beq lbl_80251C64
/* 80251BD0 0024EB30 3C 60 80 3F */ lis r3, lbl_803E9118@ha
/* 80251BD0 0024EB30 3C 60 80 3F */ lis r3, __vt__23CElectricBeamProjectile@ha
/* 80251BD4 0024EB34 34 1E 04 78 */ addic. r0, r30, 0x478
/* 80251BD8 0024EB38 38 03 91 18 */ addi r0, r3, lbl_803E9118@l
/* 80251BD8 0024EB38 38 03 91 18 */ addi r0, r3, __vt__23CElectricBeamProjectile@l
/* 80251BDC 0024EB3C 90 1E 00 00 */ stw r0, 0(r30)
/* 80251BE0 0024EB40 41 82 00 24 */ beq lbl_80251C04
/* 80251BE4 0024EB44 80 7E 04 78 */ lwz r3, 0x478(r30)
@ -161,8 +161,8 @@ lbl_80251CFC:
/* 80251D30 0024EC90 38 21 00 30 */ addi r1, r1, 0x30
/* 80251D34 0024EC94 4E 80 00 20 */ blr
.global sub_80251d38
sub_80251d38:
.global ResetBeam__23CElectricBeamProjectileFR13CStateManagerb
ResetBeam__23CElectricBeamProjectileFR13CStateManagerb:
/* 80251D38 0024EC98 94 21 FF F0 */ stwu r1, -0x10(r1)
/* 80251D3C 0024EC9C 7C 08 02 A6 */ mflr r0
/* 80251D40 0024ECA0 90 01 00 14 */ stw r0, 0x14(r1)
@ -205,8 +205,8 @@ lbl_80251DBC:
/* 80251DCC 0024ED2C 38 21 00 10 */ addi r1, r1, 0x10
/* 80251DD0 0024ED30 4E 80 00 20 */ blr
.global sub_80251dd4
sub_80251dd4:
.global Fire__23CElectricBeamProjectileFRC12CTransform4fR13CStateManagerb
Fire__23CElectricBeamProjectileFRC12CTransform4fR13CStateManagerb:
/* 80251DD4 0024ED34 94 21 FF F0 */ stwu r1, -0x10(r1)
/* 80251DD8 0024ED38 7C 08 02 A6 */ mflr r0
/* 80251DDC 0024ED3C 38 80 00 01 */ li r4, 1
@ -256,8 +256,8 @@ lbl_80251E70:
/* 80251E7C 0024EDDC 38 21 00 10 */ addi r1, r1, 0x10
/* 80251E80 0024EDE0 4E 80 00 20 */ blr
.global sub_80251e84
sub_80251e84:
.global UpdateFx__23CElectricBeamProjectileFRC12CTransform4ffR13CStateManager
UpdateFx__23CElectricBeamProjectileFRC12CTransform4ffR13CStateManager:
/* 80251E84 0024EDE4 94 21 FF 70 */ stwu r1, -0x90(r1)
/* 80251E88 0024EDE8 7C 08 02 A6 */ mflr r0
/* 80251E8C 0024EDEC 90 01 00 94 */ stw r0, 0x94(r1)
@ -569,8 +569,8 @@ lbl_802522DC:
/* 802522F8 0024F258 38 21 00 90 */ addi r1, r1, 0x90
/* 802522FC 0024F25C 4E 80 00 20 */ blr
.global nullsub_65
nullsub_65:
.global Touch__23CElectricBeamProjectileFR6CActorR13CStateManager
Touch__23CElectricBeamProjectileFR6CActorR13CStateManager:
/* 80252300 0024F260 4E 80 00 20 */ blr
.global Accept__23CElectricBeamProjectileFR8IVisitor
@ -590,8 +590,8 @@ Accept__23CElectricBeamProjectileFR8IVisitor:
/* 80252334 0024F294 38 21 00 10 */ addi r1, r1, 0x10
/* 80252338 0024F298 4E 80 00 20 */ blr
.global __ct__23CElectricBeamProjectile
__ct__23CElectricBeamProjectile:
.global "__ct__23CElectricBeamProjectileFRC28TToken<18CWeaponDescription>11EWeaponTypeRC17SElectricBeamInfoRC12CTransform4f14EMaterialTypesRC11CDamageInfo9TUniqueId7TAreaId9TUniqueId17EProjectileAttrib"
"__ct__23CElectricBeamProjectileFRC28TToken<18CWeaponDescription>11EWeaponTypeRC17SElectricBeamInfoRC12CTransform4f14EMaterialTypesRC11CDamageInfo9TUniqueId7TAreaId9TUniqueId17EProjectileAttrib":
/* 8025233C 0024F29C 94 21 FF 60 */ stwu r1, -0xa0(r1)
/* 80252340 0024F2A0 7C 08 02 A6 */ mflr r0
/* 80252344 0024F2A4 3D 60 80 3D */ lis r11, lbl_803D4B78@ha
@ -640,12 +640,12 @@ __ct__23CElectricBeamProjectile:
/* 802523F0 0024F350 C0 5B 00 10 */ lfs f2, 0x10(r27)
/* 802523F4 0024F354 D8 01 00 60 */ stfd f0, 0x60(r1)
/* 802523F8 0024F358 81 01 00 64 */ lwz r8, 0x64(r1)
/* 802523FC 0024F35C 4B F4 70 91 */ bl "__ct__15CBeamProjectileFRC28TToken<18CWeaponDescription>RCQ24rstl66basic_string<c,Q24rstl14char_traits<c>,Q24rstl17rmemory_allocator>11EWeaponTypeRC12CTransform4fiff14EMaterialTypesRC11CDamageInfo9TUniqueId9TUniqueIdUib"
/* 802523FC 0024F35C 4B F4 70 91 */ bl "__ct__15CBeamProjectileFRC28TToken<18CWeaponDescription>RCQ24rstl66basic_string<c,Q24rstl14char_traits<c>,Q24rstl17rmemory_allocator>11EWeaponTypeRC12CTransform4fiff14EMaterialTypesRC11CDamageInfo9TUniqueId7TAreaId9TUniqueId17EProjectileAttribb"
/* 80252400 0024F360 38 61 00 4C */ addi r3, r1, 0x4c
/* 80252404 0024F364 48 0E B6 DD */ bl "internal_dereference__Q24rstl66basic_string<c,Q24rstl14char_traits<c>,Q24rstl17rmemory_allocator>Fv"
/* 80252408 0024F368 3C 80 80 3F */ lis r4, lbl_803E9118@ha
/* 80252408 0024F368 3C 80 80 3F */ lis r4, __vt__23CElectricBeamProjectile@ha
/* 8025240C 0024F36C 3C 60 80 3D */ lis r3, lbl_803D4B78@ha
/* 80252410 0024F370 38 04 91 18 */ addi r0, r4, lbl_803E9118@l
/* 80252410 0024F370 38 04 91 18 */ addi r0, r4, __vt__23CElectricBeamProjectile@l
/* 80252414 0024F374 3A A0 00 00 */ li r21, 0
/* 80252418 0024F378 38 63 4B 78 */ addi r3, r3, lbl_803D4B78@l
/* 8025241C 0024F37C 90 18 00 00 */ stw r0, 0(r24)

View File

@ -2387,7 +2387,7 @@ Accept__17CPlasmaProjectileFR8IVisitor:
/* 80178C94 00175BF4 81 1E 00 18 */ lwz r8, 0x18(r30)
/* 80178C98 00175BF8 C0 3E 00 1C */ lfs f1, 0x1c(r30)
/* 80178C9C 00175BFC C0 5E 00 38 */ lfs f2, 0x38(r30)
/* 80178CA0 00175C00 48 02 07 ED */ bl "__ct__15CBeamProjectileFRC28TToken<18CWeaponDescription>RCQ24rstl66basic_string<c,Q24rstl14char_traits<c>,Q24rstl17rmemory_allocator>11EWeaponTypeRC12CTransform4fiff14EMaterialTypesRC11CDamageInfo9TUniqueId9TUniqueIdUib"
/* 80178CA0 00175C00 48 02 07 ED */ bl "__ct__15CBeamProjectileFRC28TToken<18CWeaponDescription>RCQ24rstl66basic_string<c,Q24rstl14char_traits<c>,Q24rstl17rmemory_allocator>11EWeaponTypeRC12CTransform4fiff14EMaterialTypesRC11CDamageInfo9TUniqueId7TAreaId9TUniqueId17EProjectileAttribb"
/* 80178CA4 00175C04 3C 60 80 3E */ lis r3, lbl_803E3F00@ha
/* 80178CA8 00175C08 C0 22 A1 C0 */ lfs f1, lbl_805ABEE0@sda21(r2)
/* 80178CAC 00175C0C 38 03 3F 00 */ addi r0, r3, lbl_803E3F00@l

View File

@ -352,7 +352,7 @@ LIBS = [
["MetroidPrime/CMemoryCardDriver", False],
"MetroidPrime/CSaveGameScreen",
"MetroidPrime/Enemies/CAtomicBeta",
"MetroidPrime/Weapons/CElectricBeamProjectile",
["MetroidPrime/Weapons/CElectricBeamProjectile", False],
"MetroidPrime/Enemies/CRidley",
["MetroidPrime/Enemies/CPuffer", False],
["MetroidPrime/ScriptObjects/CFire", False],

View File

@ -39,8 +39,19 @@ public:
void AddModifier(CWarp*) override;
uint Get4CharId() const override;
void SetOverrideIPos(const CVector3f& vec) { x178_overrideIPos = vec; }
void SetOverrideIVel(const CVector3f& vec) { x188_overrideIVel = vec; }
void SetOverrideFPos(const CVector3f& vec) { x198_overrideFPos = vec; }
void SetOverrideFVel(const CVector3f& vec) { x1a8_overrideFVel = vec; }
private:
uchar x4_pad[0x43c];
uchar x1c_pad[0x15c];
rstl::optional_object<CVector3f> x178_overrideIPos;
rstl::optional_object<CVector3f> x188_overrideIVel;
rstl::optional_object<CVector3f> x198_overrideFPos;
rstl::optional_object<CVector3f> x1a8_overrideFVel;
uchar x1b8_pad[0x2a0];
};
CHECK_SIZEOF(CParticleElectric, 0x458)

View File

@ -14,10 +14,22 @@ public:
kDT_Actor,
kDT_World,
};
CBeamProjectile(const TToken<CWeaponDescription>& wDesc, const rstl::string& name, EWeaponType wType,
const CTransform4f& xf, int maxLength, float beamRadius, float travelSpeed,
EMaterialTypes matType, const CDamageInfo& dInfo, TUniqueId uid, TAreaId aid, TUniqueId owner,
EProjectileAttrib attribs, bool growingBeam);
~CBeamProjectile() override;
virtual void UpdateFx(const CTransform4f&, float, CStateManager&);
virtual void ResetBeam(CStateManager&, bool);
virtual void Fire(const CTransform4f&, CStateManager&, bool) = 0;
void CauseDamage(bool b) { x464_25_enableTouchDamage = b; }
EDamageType GetDamageType() const { return x2f8_damageType; }
const CVector3f& GetCurrentPos() const { return x318_collisionPoint; }
const CVector3f& GetSurfaceNormal() const { return x30c_collisionNormal; }
const CTransform4f& GetBeamTransform() const { return x324_xf; }
private:
int x2e8_intMaxLength;

View File

@ -0,0 +1,49 @@
#ifndef _CELECTRICBEAMPROJECTILE
#define _CELECTRICBEAMPROJECTILE
#include "MetroidPrime/Weapons/CBeamProjectile.hpp"
class CParticleElectric;
class CElectricDescription;
struct SElectricBeamInfo {
TToken< CElectricDescription > x0_electricDescription;
float x8_maxLength;
float xc_radius;
float x10_travelSpeed;
CAssetId x14_particleId;
float x18_fadeSpeed;
float x1c_damageInterval;
};
class CElectricBeamProjectile : public CBeamProjectile {
public:
CElectricBeamProjectile(const TToken< CWeaponDescription >&, EWeaponType,
const SElectricBeamInfo&, const CTransform4f&, EMaterialTypes,
const CDamageInfo&, TUniqueId, TAreaId, TUniqueId, EProjectileAttrib);
// CEntity
void Accept(IVisitor&) override;
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override;
// CActor
void AddToRenderer(const CFrustumPlanes&, const CStateManager&) const override;
void Touch(CActor&, CStateManager&) override;
// CBeamProjectile
void UpdateFx(const CTransform4f&, float, CStateManager&) override;
void ResetBeam(CStateManager&, bool) override;
void Fire(const CTransform4f&, CStateManager&, bool) override;
private:
rstl::single_ptr< CParticleElectric > x468_electric;
TLockedToken< CGenDescription > x46c_genDescription;
rstl::single_ptr< CElementGen > x478_elementGen;
float x47c_fadeSpeed;
float x480_intensity;
float x484_damageTimer;
float x488_damageInterval;
bool x48c_;
};
#endif // _CELECTRICBEAMPROJECTILE

View File

@ -39,6 +39,7 @@ public:
void SetHitProjectileOwner(TUniqueId id) { x2c4_hitProjectileOwner = id; }
bool GetWeaponActive() const { return x2e4_24_active; }
void DeleteProjectileLight(CStateManager&);
protected:
rstl::optional_object< TLockedToken< CGenDescription > > x158_visorParticle;

View File

@ -0,0 +1,123 @@
#include "MetroidPrime/Weapons/CElectricBeamProjectile.hpp"
#include "MetaRender/CCubeRenderer.hpp"
#include "Kyoto/Math/CloseEnough.hpp"
#include "Kyoto/Particles/CElementGen.hpp"
#include "Kyoto/Particles/CParticleElectric.hpp"
#include "rstl/math.hpp"
CElectricBeamProjectile::CElectricBeamProjectile(const TToken< CWeaponDescription >& wDesc,
EWeaponType wType, const SElectricBeamInfo& elec,
const CTransform4f& xf, EMaterialTypes matTypes,
const CDamageInfo& dInfo, TUniqueId uid,
TAreaId areaId, TUniqueId owner,
EProjectileAttrib attribs)
: CBeamProjectile(wDesc, rstl::string_l("ElectricBeamProjectile"), wType, xf, elec.x8_maxLength,
elec.xc_radius, elec.x10_travelSpeed, matTypes, dInfo, uid, areaId, owner,
attribs, false)
, x468_electric(new CParticleElectric(elec.x0_electricDescription))
, x46c_genDescription(gpSimplePool->GetObj(SObjectTag('PART', elec.x14_particleId)))
, x478_elementGen(new CElementGen(x46c_genDescription))
, x47c_fadeSpeed(elec.x18_fadeSpeed)
, x484_damageTimer(0.f)
, x488_damageInterval(elec.x1c_damageInterval)
, x48c_(false) {
x478_elementGen->SetParticleEmission(false);
x468_electric->SetParticleEmission(false);
}
void CElectricBeamProjectile::Accept(IVisitor& visitor) { visitor.Visit(*this); }
void CElectricBeamProjectile::Touch(CActor&, CStateManager&) {}
void CElectricBeamProjectile::AddToRenderer(const CFrustumPlanes&, const CStateManager& mgr) const {
if (GetActive()) {
gpRender->AddParticleGen(*x478_elementGen);
gpRender->AddParticleGen(*x468_electric);
}
}
void CElectricBeamProjectile::UpdateFx(const CTransform4f& xf, float dt, CStateManager& mgr) {
if (!GetActive())
return;
if (x484_damageTimer <= 0.f)
CauseDamage(true);
if (GetDamageType() == kDT_Actor) {
x484_damageTimer = x488_damageInterval;
CauseDamage(false);
}
x484_damageTimer -= dt;
if (!close_enough(x47c_fadeSpeed, 0.f)) {
float fVar1 = x48c_ ? 1.f : -1.f;
x480_intensity = rstl::min_val(1.f, dt * (fVar1 / x47c_fadeSpeed) + x480_intensity);
if (x480_intensity < 0.f) {
ResetBeam(mgr, true);
}
} else {
x480_intensity = 1.f;
}
CBeamProjectile::UpdateFx(xf, dt, mgr);
x478_elementGen->SetModulationColor(
CColor::Lerp(CColor::Black(), CColor::White(), x480_intensity));
bool hasDamage = GetDamageType() != kDT_None;
if (hasDamage) {
x478_elementGen->SetGlobalOrientation(
CTransform4f::LookAt(CVector3f::Zero(), GetSurfaceNormal(), CVector3f::Up()));
x478_elementGen->SetGlobalTranslation(GetCurrentPos() + (0.001f * GetSurfaceNormal()));
}
x478_elementGen->SetParticleEmission(hasDamage);
x478_elementGen->Update(dt);
x468_electric->SetModulationColor(CColor::Lerp(CColor::Black(), CColor::White(), x480_intensity));
x468_electric->SetParticleEmission(true);
CVector3f dist = GetCurrentPos() - GetBeamTransform().GetTranslation();
if (dist.CanBeNormalized()) {
dist.Normalize();
}
x468_electric->SetOverrideIPos(GetBeamTransform().GetTranslation());
x468_electric->SetOverrideIVel(dist);
x468_electric->SetOverrideFPos(GetCurrentPos());
x468_electric->SetOverrideFVel(-dist);
x468_electric->Update(dt);
}
void CElectricBeamProjectile::ResetBeam(CStateManager& mgr, bool b) {
if (b) {
SetActive(false);
x478_elementGen->SetParticleEmission(false);
x468_electric->SetParticleEmission(false);
CBeamProjectile::ResetBeam(mgr, true);
} else {
x48c_ = false;
}
}
void CElectricBeamProjectile::Fire(const CTransform4f&, CStateManager&, bool) {
x48c_ = true;
SetActive(true);
x480_intensity = 0.f;
}
void CElectricBeamProjectile::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid,
CStateManager& mgr) {
switch (msg) {
case kSM_Registered:
mgr.AddWeaponId(GetOwnerId(), GetWeaponType());
CauseDamage(true);
break;
case kSM_Deleted:
DeleteProjectileLight(mgr);
break;
default:
break;
}
CGameProjectile::AcceptScriptMsg(msg, uid, mgr);
}