mirror of https://github.com/PrimeDecomp/prime.git
parent
8f0b4b4770
commit
cc64bb8b81
|
@ -3,8 +3,8 @@
|
|||
.section .data
|
||||
.balign 8
|
||||
|
||||
.global lbl_803E58C0
|
||||
lbl_803E58C0:
|
||||
.global __vt__15CScriptVisorGoo
|
||||
__vt__15CScriptVisorGoo:
|
||||
# ROM: 0x3E28C0
|
||||
.4byte 0
|
||||
.4byte 0
|
||||
|
@ -482,9 +482,9 @@ __dt__15CScriptVisorGooFv:
|
|||
/* 801D75B8 001D4518 93 C1 00 08 */ stw r30, 8(r1)
|
||||
/* 801D75BC 001D451C 7C 7E 1B 79 */ or. r30, r3, r3
|
||||
/* 801D75C0 001D4520 41 82 00 54 */ beq lbl_801D7614
|
||||
/* 801D75C4 001D4524 3C 60 80 3E */ lis r3, lbl_803E58C0@ha
|
||||
/* 801D75C4 001D4524 3C 60 80 3E */ lis r3, __vt__15CScriptVisorGoo@ha
|
||||
/* 801D75C8 001D4528 34 1E 00 F0 */ addic. r0, r30, 0xf0
|
||||
/* 801D75CC 001D452C 38 03 58 C0 */ addi r0, r3, lbl_803E58C0@l
|
||||
/* 801D75CC 001D452C 38 03 58 C0 */ addi r0, r3, __vt__15CScriptVisorGoo@l
|
||||
/* 801D75D0 001D4530 90 1E 00 00 */ stw r0, 0(r30)
|
||||
/* 801D75D4 001D4534 41 82 00 10 */ beq lbl_801D75E4
|
||||
/* 801D75D8 001D4538 38 7E 00 F0 */ addi r3, r30, 0xf0
|
||||
|
@ -570,9 +570,9 @@ lbl_801D7614:
|
|||
/* 801D7700 001D4660 38 61 00 D0 */ addi r3, r1, 0xd0
|
||||
/* 801D7704 001D4664 38 80 FF FF */ li r4, -1
|
||||
/* 801D7708 001D4668 4B F3 F3 45 */ bl __dt__10CModelDataFv
|
||||
/* 801D770C 001D466C 3C 60 80 3E */ lis r3, lbl_803E58C0@ha
|
||||
/* 801D770C 001D466C 3C 60 80 3E */ lis r3, __vt__15CScriptVisorGoo@ha
|
||||
/* 801D7710 001D4670 3A BA 00 E8 */ addi r21, r26, 0xe8
|
||||
/* 801D7714 001D4674 38 03 58 C0 */ addi r0, r3, lbl_803E58C0@l
|
||||
/* 801D7714 001D4674 38 03 58 C0 */ addi r0, r3, __vt__15CScriptVisorGoo@l
|
||||
/* 801D7718 001D4678 38 61 00 28 */ addi r3, r1, 0x28
|
||||
/* 801D771C 001D467C 90 1A 00 00 */ stw r0, 0(r26)
|
||||
/* 801D7720 001D4680 38 80 00 00 */ li r4, 0
|
||||
|
|
|
@ -286,7 +286,7 @@ LIBS = [
|
|||
"MetroidPrime/Player/CGameState",
|
||||
["MetroidPrime/ScriptObjects/CScriptVisorFlare", False],
|
||||
["MetroidPrime/ScriptObjects/CScriptWorldTeleporter", False],
|
||||
"MetroidPrime/ScriptObjects/CScriptVisorGoo",
|
||||
["MetroidPrime/ScriptObjects/CScriptVisorGoo", False],
|
||||
"MetroidPrime/Enemies/CJellyZap",
|
||||
["MetroidPrime/ScriptObjects/CScriptControllerAction", False],
|
||||
["MetroidPrime/Weapons/GunController/CGunMotion", False],
|
||||
|
|
|
@ -12,6 +12,7 @@ class CMath {
|
|||
public:
|
||||
static float FastCosR(float v);
|
||||
static float FastSinR(float v);
|
||||
static float FastArcCosR(float v);
|
||||
static inline float FastFmod(float x, float y) {
|
||||
int v = static_cast< int >(x * (1.f / y));
|
||||
return x - v * y;
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef _CSCRIPTVISORGOO
|
||||
#define _CSCRIPTVISORGOO
|
||||
|
||||
#include "MetroidPrime/CActor.hpp"
|
||||
|
||||
class CGenDescription;
|
||||
class CElectricDescription;
|
||||
|
||||
class CScriptVisorGoo : public CActor {
|
||||
public:
|
||||
CScriptVisorGoo(TUniqueId uid, const rstl::string& name, const CEntityInfo& info,
|
||||
const CTransform4f& xf, CAssetId particle, CAssetId electric, float minDist,
|
||||
float maxDist, float nearProb, float farProb, const CColor& color, int sfx,
|
||||
bool forceShow, bool active);
|
||||
~CScriptVisorGoo();
|
||||
|
||||
void Accept(IVisitor& visitor) override;
|
||||
void Think(float, CStateManager& stateMgr) override;
|
||||
void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr) override;
|
||||
void AddToRenderer(const CFrustumPlanes&, const CStateManager&) const override;
|
||||
void Render(const CStateManager&) const override;
|
||||
rstl::optional_object< CAABox > GetTouchBounds() const override;
|
||||
void Touch(CActor&, CStateManager&) override;
|
||||
|
||||
private:
|
||||
TToken< CGenDescription > xe8_particleDesc;
|
||||
TToken< CElectricDescription > xf0_electricDesc;
|
||||
ushort xf8_sfx;
|
||||
CAssetId xfc_particleId;
|
||||
CAssetId x100_electricId;
|
||||
float x104_minDist;
|
||||
float x108_maxDist;
|
||||
float x10c_nearProb;
|
||||
float x110_farProb;
|
||||
CColor x114_color;
|
||||
bool x118_24_angleTest : 1;
|
||||
};
|
||||
|
||||
#endif // _CSCRIPTVISORGOO
|
|
@ -0,0 +1,142 @@
|
|||
#include "MetroidPrime/ScriptObjects/CScriptVisorGoo.hpp"
|
||||
|
||||
#include "MetroidPrime/CActorParameters.hpp"
|
||||
#include "MetroidPrime/CStateManager.hpp"
|
||||
#include "MetroidPrime/Cameras/CCameraManager.hpp"
|
||||
#include "MetroidPrime/Player/CPlayer.hpp"
|
||||
#include "MetroidPrime/ScriptObjects/CHUDBillboardEffect.hpp"
|
||||
|
||||
#include "Kyoto/Audio/CSfxManager.hpp"
|
||||
|
||||
#include "rstl/math.hpp"
|
||||
|
||||
CScriptVisorGoo::CScriptVisorGoo(TUniqueId uid, const rstl::string& name, const CEntityInfo& info,
|
||||
const CTransform4f& xf, CAssetId particle, CAssetId electric,
|
||||
float minDist, float maxDist, float nearProb, float farProb,
|
||||
const CColor& color, int sfx, bool forceShow, bool active)
|
||||
: CActor(uid, active, name, info, xf, CModelData::CModelDataNull(), CMaterialList(),
|
||||
CActorParameters::None(), kInvalidUniqueId)
|
||||
, xe8_particleDesc(nullptr)
|
||||
, xf0_electricDesc(nullptr)
|
||||
, xf8_sfx(CSfxManager::TranslateSFXID(sfx))
|
||||
, xfc_particleId(particle)
|
||||
, x100_electricId(electric)
|
||||
, x104_minDist(minDist)
|
||||
, x108_maxDist(rstl::max_val(maxDist, minDist + 0.01f))
|
||||
, x10c_nearProb(nearProb)
|
||||
, x110_farProb(farProb)
|
||||
, x114_color(color) {
|
||||
x118_24_angleTest = !forceShow;
|
||||
if (particle != kInvalidAssetId) {
|
||||
xe8_particleDesc = gpSimplePool->GetObj(SObjectTag('PART', particle));
|
||||
}
|
||||
if (electric != kInvalidAssetId) {
|
||||
xf0_electricDesc = gpSimplePool->GetObj(SObjectTag('ELSC', electric));
|
||||
}
|
||||
}
|
||||
|
||||
CScriptVisorGoo::~CScriptVisorGoo() {}
|
||||
|
||||
void CScriptVisorGoo::Think(float, CStateManager& mgr) {
|
||||
if (GetActive()) {
|
||||
bool loaded = false;
|
||||
if (xfc_particleId != kInvalidAssetId) {
|
||||
if (xe8_particleDesc.IsLoaded()) {
|
||||
if (x100_electricId != kInvalidAssetId) {
|
||||
if (xf0_electricDesc.IsLoaded()) {
|
||||
loaded = true;
|
||||
}
|
||||
} else {
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (xf0_electricDesc.IsLoaded()) {
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (loaded) {
|
||||
bool showGoo = false;
|
||||
if (mgr.GetPlayer()->GetCameraState() == CPlayer::kCS_FirstPerson) {
|
||||
const CVector3f eyeToGoo = GetTranslation() - mgr.GetPlayer()->GetEyePosition();
|
||||
const float eyeToGooDist = eyeToGoo.Magnitude();
|
||||
if (eyeToGooDist >= x104_minDist && eyeToGooDist <= x108_maxDist) {
|
||||
if (x118_24_angleTest) {
|
||||
CVector3f colNorm = mgr.GetCameraManager()
|
||||
->GetCurrentCameraTransform(mgr)
|
||||
.GetColumn(kDY)
|
||||
.AsNormalized();
|
||||
float angleThresh = 45.f;
|
||||
float angle = CMath::Rad2Deg(CMath::FastArcCosR(
|
||||
CVector3f::Dot(eyeToGoo.AsNormalized(), colNorm))) *
|
||||
360.f;
|
||||
if (eyeToGooDist < 4.f) {
|
||||
angleThresh *= 4.f / eyeToGooDist;
|
||||
angleThresh = rstl::min_val(angleThresh, 90.f);
|
||||
}
|
||||
if (angle <= angleThresh) {
|
||||
showGoo = true;
|
||||
}
|
||||
} else {
|
||||
showGoo = true;
|
||||
}
|
||||
if (showGoo) {
|
||||
const float t = (x108_maxDist - eyeToGooDist) / (x108_maxDist - x104_minDist);
|
||||
float prob = t * x10c_nearProb + (1.0f - t) * x110_farProb;
|
||||
if (mgr.Random()->Float() * 100.f <= prob) {
|
||||
mgr.AddObject(new CHUDBillboardEffect(
|
||||
xfc_particleId != kInvalidAssetId
|
||||
? rstl::optional_object< TToken< CGenDescription > >(xe8_particleDesc)
|
||||
: rstl::optional_object_null(),
|
||||
x100_electricId != kInvalidAssetId
|
||||
? rstl::optional_object< TToken< CElectricDescription > >(xf0_electricDesc)
|
||||
: rstl::optional_object_null(),
|
||||
mgr.AllocateUniqueId(), true, rstl::string_l("VisorGoo"),
|
||||
CHUDBillboardEffect::GetNearClipDistance(mgr),
|
||||
CHUDBillboardEffect::GetScaleForPOV(mgr), x114_color, CVector3f(1.f, 1.f, 1.f),
|
||||
CVector3f(0.f, 0.f, 0.f)));
|
||||
CSfxManager::SfxStart(xf8_sfx, 0x7f, 0x40, false, CSfxManager::kMedPriority);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mgr.FreeScriptObject(GetUniqueId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CScriptVisorGoo::Touch(CActor& other, CStateManager& mgr) {
|
||||
// Empty
|
||||
}
|
||||
|
||||
rstl::optional_object< CAABox > CScriptVisorGoo::GetTouchBounds() const {
|
||||
return rstl::optional_object_null();
|
||||
}
|
||||
|
||||
void CScriptVisorGoo::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId,
|
||||
CStateManager& mgr) {
|
||||
switch (msg) {
|
||||
case kSM_Activate:
|
||||
if (xfc_particleId != kInvalidAssetId) {
|
||||
xe8_particleDesc.Lock();
|
||||
}
|
||||
if (x100_electricId != kInvalidAssetId) {
|
||||
xf0_electricDesc.Lock();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
CActor::AcceptScriptMsg(msg, objId, mgr);
|
||||
}
|
||||
|
||||
void CScriptVisorGoo::Render(const CStateManager& mgr) const {
|
||||
// Empty
|
||||
}
|
||||
|
||||
void CScriptVisorGoo::AddToRenderer(const CFrustumPlanes& frustum, const CStateManager& mgr) const {
|
||||
// Empty
|
||||
}
|
||||
|
||||
void CScriptVisorGoo::Accept(IVisitor& visitor) { visitor.Visit(*this); }
|
Loading…
Reference in New Issue