mirror of
https://github.com/AxioDL/metaforce.git
synced 2025-12-14 02:06:09 +00:00
Implement CEyeBall, disable CPuddleToadGamma (preventing softlocks), initial CSpankWeed
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
#include "Weapon/CGameProjectile.hpp"
|
||||
#include "Weapon/CPlasmaProjectile.hpp"
|
||||
#include "World/CPlayer.hpp"
|
||||
#include "World/CWorld.hpp"
|
||||
#include "World/CGameArea.hpp"
|
||||
#include "CStateManager.hpp"
|
||||
#include "TCastTo.hpp"
|
||||
namespace urde::MP1
|
||||
@@ -13,13 +15,18 @@ CEyeball::CEyeball(TUniqueId uid, std::string_view name, CPatterned::EFlavorType
|
||||
u32 w1, u32 w2, u32 w3, u32 w4, u32 w5,
|
||||
bool b1, const CActorParameters& actParms)
|
||||
: CPatterned(ECharacter::EyeBall, uid, name, flavor, info, xf, std::move(mData), pInfo, EMovementType::Flyer,
|
||||
EColliderType::Zero, EBodyType::Restricted, actParms, EKnockBackVariant::Medium), x568_(f1), x56c_(f2),
|
||||
EColliderType::Zero, EBodyType::Restricted, actParms, EKnockBackVariant::Medium), x568_attackDelay(f1), x56c_maxAttackDelay(f2),
|
||||
x570_boneTracking(*GetModelData()->GetAnimationData(), "Eye"sv, zeus::degToRad(45.f),
|
||||
zeus::degToRad(180.f), true), x5b4_projectileInfo(aId1, dInfo), x5dc_(aId2), x5e0_(aId3),
|
||||
x5e4_(aId4),
|
||||
x5e8_(aId5), x5f4_(w1), x5f8_(w2), x5fc_(w3), x600_(w4), x604_(CSfxManager::TranslateSFXID(w5)), x60c_24_(false),
|
||||
x60c_25_(false), x60c_26_alert(false), x60c_27_(b1), x60c_28_(false)
|
||||
x5e8_(aId5), x604_beamSfxId(CSfxManager::TranslateSFXID(w5)), x60c_24_canAttack(false),
|
||||
x60c_25_playerInRange(false), x60c_26_alert(false), x60c_27_attackDisabled(b1), x60c_28_firingBeam(false)
|
||||
{
|
||||
x5f4_animIdxs[0] = w1;
|
||||
x5f4_animIdxs[1] = w2;
|
||||
x5f4_animIdxs[2] = w3;
|
||||
x5f4_animIdxs[3] = w4;
|
||||
|
||||
x460_knockBackController.SetAutoResetImpulse(false);
|
||||
}
|
||||
|
||||
@@ -61,10 +68,10 @@ void CEyeball::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateMa
|
||||
if (x5ec_projectileId != kInvalidUniqueId)
|
||||
{
|
||||
mgr.FreeScriptObject(x5ec_projectileId);
|
||||
if (x608_)
|
||||
if (x608_beamSfx)
|
||||
{
|
||||
CSfxManager::RemoveEmitter(x608_);
|
||||
x608_.reset();
|
||||
CSfxManager::RemoveEmitter(x608_beamSfx);
|
||||
x608_beamSfx.reset();
|
||||
}
|
||||
}
|
||||
x5ec_projectileId = kInvalidUniqueId;
|
||||
@@ -76,6 +83,47 @@ void CEyeball::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateMa
|
||||
CPatterned::AcceptScriptMsg(msg, uid, mgr);
|
||||
}
|
||||
|
||||
static float kMinAngle = std::cos(zeus::degToRad(45.f));
|
||||
void CEyeball::Think(float dt, CStateManager& mgr)
|
||||
{
|
||||
CPatterned::Think(dt, mgr);
|
||||
if (!GetActive())
|
||||
return;
|
||||
|
||||
CPlayer& player = mgr.GetPlayer();
|
||||
zeus::CVector3f direction = (player.GetTranslation() - GetTranslation()).normalized();
|
||||
|
||||
x60c_25_playerInRange = (player.GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed &&
|
||||
direction.dot(GetTransform().frontVector()) > kMinAngle);
|
||||
|
||||
if (x60c_25_playerInRange)
|
||||
{
|
||||
x570_boneTracking.SetActive(true);
|
||||
x5a8_targetPosition = player.GetTranslation() - (0.5f * player.GetVelocity());
|
||||
x570_boneTracking.SetTargetPosition(x5a8_targetPosition);
|
||||
x570_boneTracking.Update(dt);
|
||||
ModelData()->AnimationData()->PreRender();
|
||||
x570_boneTracking.PreRender(mgr, *ModelData()->AnimationData(), GetTransform(), GetModelData()->GetScale(),
|
||||
*x450_bodyController.get());
|
||||
} else
|
||||
x570_boneTracking.SetActive(false);
|
||||
|
||||
if (GetActive())
|
||||
{
|
||||
CPlasmaProjectile* projectile = static_cast<CPlasmaProjectile*>(mgr.ObjectById(x5ec_projectileId));
|
||||
if (projectile && projectile->GetActive())
|
||||
projectile->UpdateFX(GetLctrTransform(skEyeLocator), dt, mgr);
|
||||
}
|
||||
|
||||
if (x60c_28_firingBeam)
|
||||
{
|
||||
const CGameArea* area = mgr.GetWorld()->GetAreaAlways(GetAreaIdAlways());
|
||||
if (area->GetActive() && area->IsPostConstructed() &&
|
||||
area->GetPostConstructed()->x10dc_occlusionState == CGameArea::EOcclusionState::Occluded)
|
||||
ResetBeamState(mgr);
|
||||
}
|
||||
}
|
||||
|
||||
void CEyeball::CreateBeam(CStateManager& mgr)
|
||||
{
|
||||
if (x5ec_projectileId != kInvalidUniqueId)
|
||||
@@ -102,8 +150,8 @@ void CEyeball::Cover(CStateManager&, EStateMsg msg, float)
|
||||
if (msg == EStateMsg::Activate)
|
||||
{
|
||||
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk);
|
||||
x60c_24_ = false;
|
||||
x330_stateMachineState.SetDelay(x568_);
|
||||
x60c_24_canAttack = false;
|
||||
x330_stateMachineState.SetDelay(x568_attackDelay);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,7 +160,7 @@ void CEyeball::Flinch(CStateManager& mgr, EStateMsg msg, float arg)
|
||||
if (msg == EStateMsg::Activate)
|
||||
{
|
||||
x32c_animState = EAnimState::One;
|
||||
x330_stateMachineState.SetDelay(x568_);
|
||||
x330_stateMachineState.SetDelay(x568_attackDelay);
|
||||
}
|
||||
else if (msg == EStateMsg::Update)
|
||||
TryCommand(mgr, pas::EAnimationState::KnockBack, CPatternedTryFunc(&CEyeball::TryFlinch), 0);
|
||||
@@ -131,31 +179,99 @@ void CEyeball::Active(CStateManager& mgr, EStateMsg msg, float)
|
||||
{
|
||||
x400_24_hitByPlayerProjectile = 0;
|
||||
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Combat);
|
||||
x60c_24_ = false;
|
||||
x60c_24_canAttack = false;
|
||||
}
|
||||
else if (msg == EStateMsg::Update)
|
||||
{
|
||||
if (x330_stateMachineState.GetDelay() > x56c_)
|
||||
x60c_24_ = true;
|
||||
if (x330_stateMachineState.GetDelay() > x56c_maxAttackDelay)
|
||||
x60c_24_canAttack = true;
|
||||
|
||||
sub802249c8();
|
||||
UpdateAnimation();
|
||||
}
|
||||
else if (msg == EStateMsg::Deactivate)
|
||||
{
|
||||
x330_stateMachineState.SetDelay(x568_);
|
||||
x330_stateMachineState.SetDelay(x568_attackDelay);
|
||||
if (CPlasmaProjectile* proj = static_cast<CPlasmaProjectile*>(mgr.ObjectById(x5ec_projectileId)))
|
||||
proj->ResetBeam(mgr, true);
|
||||
|
||||
x60c_24_ = false;
|
||||
x60c_24_canAttack = false;
|
||||
|
||||
CSfxManager::RemoveEmitter(x608_);
|
||||
x608_.reset();
|
||||
CSfxManager::RemoveEmitter(x608_beamSfx);
|
||||
x608_beamSfx.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void CEyeball::sub802249c8()
|
||||
void CEyeball::UpdateAnimation()
|
||||
{
|
||||
if (std::fabs(GetModelData()->GetAnimationData()->GetAnimTimeRemaining("Whole Body"sv) - 0.f) >= 0.00001f)
|
||||
return;
|
||||
|
||||
x5f0_currentAnim = (x5f0_currentAnim + 1) & 3;
|
||||
for (u32 i=0 ; i<4 ; ++i)
|
||||
{
|
||||
if (x5f4_animIdxs[x5f0_currentAnim] != -1)
|
||||
break;
|
||||
|
||||
x5f0_currentAnim = (x5f0_currentAnim + 1) & 3;
|
||||
}
|
||||
s32 animIdx = x5f4_animIdxs[x5f0_currentAnim];
|
||||
if (animIdx != -1)
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCScriptedCmd(animIdx, false, false, 0.f));
|
||||
}
|
||||
|
||||
void CEyeball::ResetBeamState(CStateManager& mgr)
|
||||
{
|
||||
if (CPlasmaProjectile* projectile = static_cast<CPlasmaProjectile*>(mgr.ObjectById(x5ec_projectileId)))
|
||||
projectile->ResetBeam(mgr, true);
|
||||
|
||||
x60c_28_firingBeam = false;
|
||||
if (x608_beamSfx)
|
||||
{
|
||||
CSfxManager::RemoveEmitter(x608_beamSfx);
|
||||
x608_beamSfx.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void CEyeball::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt)
|
||||
{
|
||||
if (type == EUserEventType::DamageOff)
|
||||
ResetBeamState(mgr);
|
||||
else if (type == EUserEventType::DamageOn && x60c_24_canAttack)
|
||||
FireBeam(mgr, GetLctrTransform(node.GetLocatorName()));
|
||||
else
|
||||
CPatterned::DoUserAnimEvent(mgr, node, type, dt);
|
||||
}
|
||||
|
||||
void CEyeball::FireBeam(CStateManager& mgr, const zeus::CTransform& xf)
|
||||
{
|
||||
if (CPlasmaProjectile* projectile = static_cast<CPlasmaProjectile*>(mgr.ObjectById(x5ec_projectileId)))
|
||||
{
|
||||
if (!projectile->GetActive())
|
||||
{
|
||||
projectile->Fire(xf, mgr, false);
|
||||
x60c_28_firingBeam = true;
|
||||
if (!x608_beamSfx)
|
||||
{
|
||||
CAudioSys::C3DEmitterParmData
|
||||
parmData{GetTranslation(), {}, 50.f, 0.1f, 0x1, x604_beamSfxId, 1.f /* 127 */, 0.15f /* 20 / 127 */,
|
||||
false, 127};
|
||||
x608_beamSfx = CSfxManager::AddEmitter(parmData, true, 127, true, GetAreaIdAlways());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CEyeball::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum)
|
||||
{
|
||||
CPatterned::PreRender(mgr, frustum);
|
||||
x570_boneTracking.PreRender(mgr, *ModelData()->AnimationData(), GetTransform(), GetModelData()->GetScale(),
|
||||
*x450_bodyController);
|
||||
}
|
||||
|
||||
void CEyeball::Death(CStateManager& mgr, const zeus::CVector3f& pos, EScriptObjectState state)
|
||||
{
|
||||
zeus::CTransform oldXf = GetTransform();
|
||||
CPatterned::Death(mgr, pos, state);
|
||||
SetTransform(oldXf);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user