CJellyZap fixes

This commit is contained in:
Phillip Stephens 2021-04-25 20:16:16 -07:00
parent 07c39542af
commit f1b0c4b735
Signed by: Antidote
GPG Key ID: F8BEE4C83DACA60D
3 changed files with 83 additions and 46 deletions

View File

@ -10,21 +10,22 @@ namespace metaforce::MP1 {
constexpr CMaterialFilter kPlayerFilter = CMaterialFilter::MakeInclude({EMaterialTypes::Player}); constexpr CMaterialFilter kPlayerFilter = CMaterialFilter::MakeInclude({EMaterialTypes::Player});
CJellyZap::CJellyZap(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, CJellyZap::CJellyZap(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf,
CModelData&& mData, const CDamageInfo& dInfo, bool b1, float f1, float f2, float f3, float f4, CModelData&& mData, const CDamageInfo& attackDamage, bool b1, float attackRadius, float f2,
float f5, float f6, float f7, float f8, float f9, float f10, float f11, float f12, float f3, float f4, float attackDelay, float f6, float f7, float f8, float priority,
const CPatternedInfo& pInfo, const CActorParameters& actParms) float repulseRadius, float attractRadius, float f12, const CPatternedInfo& pInfo,
const CActorParameters& actParms)
: CPatterned(ECharacter::JellyZap, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo, : CPatterned(ECharacter::JellyZap, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo,
EMovementType::Flyer, EColliderType::One, EBodyType::BiPedal, actParms, EKnockBackVariant::Medium) EMovementType::Flyer, EColliderType::One, EBodyType::BiPedal, actParms, EKnockBackVariant::Medium)
, x56c_attackDamage(dInfo) , x56c_attackDamage(attackDamage)
, x588_attackRadius(f1) , x588_attackRadius(attackRadius)
, x58c_(f2) , x58c_(f2)
, x590_(f4) , x590_(f4)
, x594_(f3) , x594_(f3)
, x598_(f8) , x598_(f8)
, x59c_priority(f9) , x59c_priority(priority)
, x5a0_repulseRadius(f10) , x5a0_repulseRadius(repulseRadius)
, x5a4_attractRadius(f11) , x5a4_attractRadius(attractRadius)
, x5a8_attackDelay(f5) , x5a8_attackDelay(attackDelay)
, x5ac_(f6) , x5ac_(f6)
, x5b0_(f7) , x5b0_(f7)
, x5b4_(f12) , x5b4_(f12)
@ -48,13 +49,20 @@ void CJellyZap::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateM
void CJellyZap::Think(float dt, CStateManager& mgr) { void CJellyZap::Think(float dt, CStateManager& mgr) {
CPatterned::Think(dt, mgr); CPatterned::Think(dt, mgr);
if (!GetActive()) if (!GetActive()) {
return; return;
if (x5b8_24_) }
if (x5b8_24_) {
x450_bodyController->FaceDirection(mgr.GetPlayer().GetTranslation() - GetTranslation(), dt); x450_bodyController->FaceDirection(mgr.GetPlayer().GetTranslation() - GetTranslation(), dt);
}
float damage = (x5b8_25_ && x450_bodyController->GetPercentageFrozen() == 0.f ? x50c_baseDamageMag + (dt / 0.3f) float damage = x50c_baseDamageMag;
: x50c_baseDamageMag - (dt / 0.75f));
if (x5b8_25_ || GetBodyController()->GetPercentageFrozen() != 0.f) {
damage -= dt / 0.75f;
} else {
damage += dt / 0.3f;
}
x50c_baseDamageMag = zeus::clamp(0.f, damage, 1.f); x50c_baseDamageMag = zeus::clamp(0.f, damage, 1.f);
} }
@ -69,7 +77,7 @@ void CJellyZap::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, E
void CJellyZap::KnockBack(const zeus::CVector3f& pos, CStateManager& mgr, const CDamageInfo& info, EKnockBackType type, void CJellyZap::KnockBack(const zeus::CVector3f& pos, CStateManager& mgr, const CDamageInfo& info, EKnockBackType type,
bool inDeferred, float magnitude) { bool inDeferred, float magnitude) {
if (info.GetWeaponMode().GetType() == EWeaponType::Ice) { if (info.GetWeaponMode().GetType() == EWeaponType::Ice) {
Freeze(mgr, {}, GetTransform().transposeRotate(pos), magnitude); Freeze(mgr, {}, GetTransform().transposeRotate(pos), x4fc_freezeDur);
} }
} }
@ -78,9 +86,9 @@ void CJellyZap::Attack(CStateManager& mgr, EStateMsg msg, float arg) {
x32c_animState = EAnimState::Ready; x32c_animState = EAnimState::Ready;
AddRepulsor(mgr); AddRepulsor(mgr);
x5b8_25_ = true; x5b8_25_ = true;
float dist = (mgr.GetPlayer().GetTranslation() - GetTranslation()).magSquared(); float dist = (mgr.GetPlayer().GetTranslation() - GetTranslation()).magnitude();
if (dist < x56c_attackDamage.GetRadius()) { if (dist < x56c_attackDamage.GetRadius()) {
float staticTimer = 3.f * (1.f - (dist / x56c_attackDamage.GetRadius())) + 2.f; float staticTimer = 3.f * (1.f - dist / x56c_attackDamage.GetRadius()) + 2.f;
if (staticTimer > mgr.GetPlayer().GetStaticTimer()) { if (staticTimer > mgr.GetPlayer().GetStaticTimer()) {
mgr.GetPlayer().SetHudDisable(staticTimer, 0.5f, 2.5f); mgr.GetPlayer().SetHudDisable(staticTimer, 0.5f, 2.5f);
mgr.GetPlayer().SetOrbitRequestForTarget(mgr.GetPlayer().GetOrbitTargetId(), mgr.GetPlayer().SetOrbitRequestForTarget(mgr.GetPlayer().GetOrbitTargetId(),
@ -103,7 +111,12 @@ void CJellyZap::Suck(CStateManager& mgr, EStateMsg msg, float arg) {
if (msg == EStateMsg::Activate) { if (msg == EStateMsg::Activate) {
x32c_animState = EAnimState::Ready; x32c_animState = EAnimState::Ready;
RemoveAllAttractors(mgr); RemoveAllAttractors(mgr);
x568_ = 1;
x400_24_hitByPlayerProjectile = false;
x5b8_24_ = true;
x5b8_25_ = true;
} else if (msg == EStateMsg::Update) { } else if (msg == EStateMsg::Update) {
auto curSuit = mgr.GetPlayerState()->GetCurrentSuit();
TryCommand(mgr, pas::EAnimationState::LoopReaction, &CPatterned::TryLoopReaction, 0); TryCommand(mgr, pas::EAnimationState::LoopReaction, &CPatterned::TryLoopReaction, 0);
x450_bodyController->GetCommandMgr().DeliverTargetVector( x450_bodyController->GetCommandMgr().DeliverTargetVector(
(mgr.GetPlayer().GetTranslation() + zeus::CVector3f(0.f, 0.f, 1.f)) - GetTranslation()); (mgr.GetPlayer().GetTranslation() + zeus::CVector3f(0.f, 0.f, 1.f)) - GetTranslation());
@ -111,12 +124,18 @@ void CJellyZap::Suck(CStateManager& mgr, EStateMsg msg, float arg) {
float intensity = mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::GravitySuit) ? 0.1f : 1.f; float intensity = mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::GravitySuit) ? 0.1f : 1.f;
zeus::CVector3f posDiff = (mgr.GetPlayer().GetTranslation() - GetTranslation()); zeus::CVector3f posDiff = (mgr.GetPlayer().GetTranslation() - GetTranslation());
float mag = 1.f / posDiff.magnitude(); float mag = 1.f / posDiff.magnitude();
mgr.GetPlayer().ApplyImpulseWR((-posDiff * mag) * (arg * (5.f * mag * mgr.GetPlayer().GetMass()) * intensity), zeus::CAxisAngle()); float massScale = mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed ? x594_
: curSuit == CPlayerState::EPlayerSuit::Gravity ? x590_
: x58c_;
mgr.GetPlayer().ApplyImpulseWR(
arg * ((5.f * massScale * mgr.GetPlayer().GetMass()) * (intensity * (mag * -posDiff))), {});
mgr.GetPlayer().UseCollisionImpulses(); mgr.GetPlayer().UseCollisionImpulses();
mgr.GetPlayer().SetAccelerationChangeTimer(2.f * arg);
mgr.GetPlayerState()->GetStaticInterference().AddSource(GetUniqueId(), 0.1f, 0.1f); mgr.GetPlayerState()->GetStaticInterference().AddSource(GetUniqueId(), 0.1f, 0.1f);
} else if (msg == EStateMsg::Deactivate) { } else if (msg == EStateMsg::Deactivate) {
x450_bodyController->GetCommandMgr().DeliverCmd(CBodyStateCmd(EBodyStateCmd::ExitState)); x450_bodyController->GetCommandMgr().DeliverCmd(CBodyStateCmd(EBodyStateCmd::ExitState));
mgr.GetPlayerState()->GetStaticInterference().RemoveSource(GetUniqueId()); mgr.GetPlayerState()->GetStaticInterference().RemoveSource(GetUniqueId());
x32c_animState = EAnimState::NotReady;
x5b8_24_ = false; x5b8_24_ = false;
x5b8_25_ = false; x5b8_25_ = false;
} }
@ -142,19 +161,20 @@ void CJellyZap::Active(CStateManager& mgr, EStateMsg msg, float arg) {
} }
} }
void CJellyZap::InActive(CStateManager& mgr, EStateMsg msg, float) { void CJellyZap::InActive(CStateManager& mgr, EStateMsg msg, float arg) {
if (msg == EStateMsg::Activate) { if (msg != EStateMsg::Activate) {
x400_24_hitByPlayerProjectile = false; return;
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed);
AddAttractor(mgr);
x568_ = 0;
} }
x400_24_hitByPlayerProjectile = false;
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed);
AddAttractor(mgr);
x568_ = 0;
} }
void CJellyZap::Flinch(CStateManager& mgr, EStateMsg msg, float arg) { void CJellyZap::Flinch(CStateManager& mgr, EStateMsg msg, float arg) {
if (msg == EStateMsg::Activate) { if (msg == EStateMsg::Activate) {
x400_24_hitByPlayerProjectile = false; x400_24_hitByPlayerProjectile = false;
x32c_animState = EAnimState::NotReady; x32c_animState = EAnimState::Ready;
x330_stateMachineState.SetDelay(x5b0_); x330_stateMachineState.SetDelay(x5b0_);
} else if (msg == EStateMsg::Update) { } else if (msg == EStateMsg::Update) {
TryCommand(mgr, pas::EAnimationState::KnockBack, &CPatterned::TryKnockBack, 0); TryCommand(mgr, pas::EAnimationState::KnockBack, &CPatterned::TryKnockBack, 0);
@ -163,11 +183,12 @@ void CJellyZap::Flinch(CStateManager& mgr, EStateMsg msg, float arg) {
} }
} }
bool CJellyZap::InAttackPosition(CStateManager& mgr, float) { bool CJellyZap::InAttackPosition(CStateManager& mgr, float arg) {
if (mgr.GetPlayer().GetFluidCounter() == 0) if (mgr.GetPlayer().GetFluidCounter() == 0) {
return false; return false;
}
return (mgr.GetPlayer().GetTranslation() - GetTranslation()).magnitude() < x588_attackRadius * x588_attackRadius; return (mgr.GetPlayer().GetTranslation() - GetTranslation()).magSquared() < x588_attackRadius * x588_attackRadius;
} }
bool CJellyZap::InDetectionRange(CStateManager& mgr, float arg) { bool CJellyZap::InDetectionRange(CStateManager& mgr, float arg) {
@ -176,8 +197,9 @@ bool CJellyZap::InDetectionRange(CStateManager& mgr, float arg) {
void CJellyZap::AddSelfToFishCloud(CStateManager& mgr, float radius, float priority, bool repulsor) { void CJellyZap::AddSelfToFishCloud(CStateManager& mgr, float radius, float priority, bool repulsor) {
for (const SConnection& conn : x20_conns) { for (const SConnection& conn : x20_conns) {
if (conn.x0_state != EScriptObjectState::ScanStart || conn.x4_msg != EScriptObjectMessage::Follow) if (conn.x0_state != EScriptObjectState::ScanStart || conn.x4_msg != EScriptObjectMessage::Follow) {
continue; continue;
}
if (TCastToPtr<CFishCloud> cloud = mgr.ObjectById(mgr.GetIdForScript(conn.x8_objId))) { if (TCastToPtr<CFishCloud> cloud = mgr.ObjectById(mgr.GetIdForScript(conn.x8_objId))) {
if (repulsor) { if (repulsor) {
cloud->AddRepulsor(GetUniqueId(), false, radius, priority); cloud->AddRepulsor(GetUniqueId(), false, radius, priority);
@ -197,8 +219,10 @@ void CJellyZap::AddAttractor(CStateManager& mgr) {
void CJellyZap::RemoveSelfFromFishCloud(CStateManager& mgr) { void CJellyZap::RemoveSelfFromFishCloud(CStateManager& mgr) {
for (const SConnection& conn : x20_conns) { for (const SConnection& conn : x20_conns) {
if (conn.x0_state != EScriptObjectState::ScanStart || conn.x4_msg != EScriptObjectMessage::Follow) if (conn.x0_state != EScriptObjectState::ScanStart || conn.x4_msg != EScriptObjectMessage::Follow) {
continue; continue;
}
if (TCastToPtr<CFishCloud> cloud = mgr.ObjectById(mgr.GetIdForScript(conn.x8_objId))) { if (TCastToPtr<CFishCloud> cloud = mgr.ObjectById(mgr.GetIdForScript(conn.x8_objId))) {
cloud->RemoveAttractor(GetUniqueId()); cloud->RemoveAttractor(GetUniqueId());
cloud->RemoveRepulsor(GetUniqueId()); cloud->RemoveRepulsor(GetUniqueId());
@ -213,22 +237,29 @@ bool CJellyZap::ClosestToPlayer(const CStateManager& mgr) const {
const float ourDistance = (playerPos - GetTranslation()).magnitude(); const float ourDistance = (playerPos - GetTranslation()).magnitude();
float closestDistance = ourDistance; float closestDistance = ourDistance;
for (CEntity* ent : mgr.GetPhysicsActorObjectList()) { for (CEntity* ent : mgr.GetPhysicsActorObjectList()) {
if (CJellyZap* zap = CPatterned::CastTo<CJellyZap>(ent)) { if (auto* zap = CPatterned::CastTo<CJellyZap>(ent)) {
if (zap->GetAreaIdAlways() != GetAreaIdAlways() || zap == this) if (zap->GetAreaIdAlways() != GetAreaIdAlways() || zap == this) {
continue; continue;
}
const float tmpDist = (playerPos - zap->GetTranslation()).magnitude(); const float tmpDist = (playerPos - zap->GetTranslation()).magnitude();
if (tmpDist < closestDistance) if (tmpDist < closestDistance) {
closestDistance = tmpDist; closestDistance = tmpDist;
}
if (zap->x5b8_25_) if (zap->x5b8_25_) {
return false; return false;
}
} }
} }
return zeus::close_enough(closestDistance, ourDistance); return zeus::close_enough(closestDistance, ourDistance);
} }
const CDamageVulnerability* CJellyZap::GetDamageVulnerability(const zeus::CVector3f& pos, const zeus::CVector3f& dir, const CDamageVulnerability* CJellyZap::GetDamageVulnerability(const zeus::CVector3f& pos, const zeus::CVector3f& dir,
const CDamageInfo& info) const { const CDamageInfo& info) const {
return CActor::GetDamageVulnerability(pos, dir, info); if (!sub801d8190()) {
return GetDamageVulnerability();
}
return &CDamageVulnerability::ReflectVulnerabilty();
} }
} // namespace metaforce::MP1 } // namespace metaforce::MP1

View File

@ -33,15 +33,17 @@ class CJellyZap : public CPatterned {
public: public:
DEFINE_PATTERNED(JellyZap); DEFINE_PATTERNED(JellyZap);
CJellyZap(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, CModelData&&, const CDamageInfo&, CJellyZap(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf,
bool, float, float, float, float, float, float, float, float, float, float, float, float, CModelData&& mData, const CDamageInfo& attackDamage, bool b1, float attackRadius, float f2, float f3, float f4, float attackDelay,
const CPatternedInfo&, const CActorParameters&); float f6, float f7, float f8, float priority, float repulseRadius, float attractRadius, float f12,
const CPatternedInfo& pInfo, const CActorParameters& actParms);
void Accept(IVisitor&) override; void Accept(IVisitor&) override;
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override;
void Think(float, CStateManager&) override; void Think(float, CStateManager&) override;
void DoUserAnimEvent(CStateManager&, const CInt32POINode&, EUserEventType, float dt) override; void DoUserAnimEvent(CStateManager&, const CInt32POINode&, EUserEventType, float dt) override;
void KnockBack(const zeus::CVector3f &, CStateManager &, const CDamageInfo &info, EKnockBackType type, bool inDeferred, float magnitude) override; void KnockBack(const zeus::CVector3f&, CStateManager&, const CDamageInfo& info, EKnockBackType type, bool inDeferred,
float magnitude) override;
const CDamageVulnerability* GetDamageVulnerability() const override { return CAi::GetDamageVulnerability(); } const CDamageVulnerability* GetDamageVulnerability() const override { return CAi::GetDamageVulnerability(); }
const CDamageVulnerability* GetDamageVulnerability(const zeus::CVector3f& pos, const zeus::CVector3f& dir, const CDamageVulnerability* GetDamageVulnerability(const zeus::CVector3f& pos, const zeus::CVector3f& dir,
const CDamageInfo& info) const override; const CDamageInfo& info) const override;

View File

@ -2560,18 +2560,20 @@ CEntity* ScriptLoader::LoadVisorGoo(CStateManager& mgr, CInputStream& in, int pr
} }
CEntity* ScriptLoader::LoadJellyZap(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) { CEntity* ScriptLoader::LoadJellyZap(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) {
if (!EnsurePropertyCount(propCount, 20, "JellyZap")) if (!EnsurePropertyCount(propCount, 20, "JellyZap")) {
return nullptr; return nullptr;
}
SScaledActorHead aHead = LoadScaledActorHead(in, mgr); SScaledActorHead aHead = LoadScaledActorHead(in, mgr);
auto pair = CPatternedInfo::HasCorrectParameterCount(in); auto pair = CPatternedInfo::HasCorrectParameterCount(in);
if (!pair.first) if (!pair.first) {
return nullptr; return nullptr;
}
CPatternedInfo pInfo(in, pair.second); CPatternedInfo pInfo(in, pair.second);
CActorParameters actParms = LoadActorParameters(in); CActorParameters actParms = LoadActorParameters(in);
CDamageInfo dInfo(in); CDamageInfo dInfo(in);
float f1 = in.readFloatBig(); float attackRadius = in.readFloatBig();
float f2 = in.readFloatBig(); float f2 = in.readFloatBig();
float f3 = in.readFloatBig(); float f3 = in.readFloatBig();
float f4 = in.readFloatBig(); float f4 = in.readFloatBig();
@ -2579,20 +2581,22 @@ CEntity* ScriptLoader::LoadJellyZap(CStateManager& mgr, CInputStream& in, int pr
float f6 = in.readFloatBig(); float f6 = in.readFloatBig();
float f7 = in.readFloatBig(); float f7 = in.readFloatBig();
float f8 = in.readFloatBig(); float f8 = in.readFloatBig();
float f9 = in.readFloatBig(); float priority = in.readFloatBig();
float f10 = in.readFloatBig(); float repulseRadius = in.readFloatBig();
float f11 = in.readFloatBig(); float attractRadius = in.readFloatBig();
float f12 = in.readFloatBig(); float f12 = in.readFloatBig();
bool b1 = in.readBool(); bool b1 = in.readBool();
const CAnimationParameters& animParms = pInfo.GetAnimationParameters(); const CAnimationParameters& animParms = pInfo.GetAnimationParameters();
if (g_ResFactory->GetResourceTypeById(animParms.GetACSFile()) != SBIG('ANCS')) if (g_ResFactory->GetResourceTypeById(animParms.GetACSFile()) != SBIG('ANCS')) {
return nullptr; return nullptr;
}
CModelData mData(CAnimRes(animParms.GetACSFile(), animParms.GetCharacter(), aHead.x40_scale, CModelData mData(CAnimRes(animParms.GetACSFile(), animParms.GetCharacter(), aHead.x40_scale,
animParms.GetInitialAnimation(), true)); animParms.GetInitialAnimation(), true));
return new MP1::CJellyZap(mgr.AllocateUniqueId(), aHead.x0_name, info, aHead.x10_transform, std::move(mData), dInfo, return new MP1::CJellyZap(mgr.AllocateUniqueId(), aHead.x0_name, info, aHead.x10_transform, std::move(mData), dInfo,
b1, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, pInfo, actParms); b1, attackRadius, f2, f3, f4, f5, f6, f7, f8, priority, repulseRadius, attractRadius, f12,
pInfo, actParms);
} }
CEntity* ScriptLoader::LoadControllerAction(CStateManager& mgr, CInputStream& in, int propCount, CEntity* ScriptLoader::LoadControllerAction(CStateManager& mgr, CInputStream& in, int propCount,