mirror of https://github.com/AxioDL/metaforce.git
CFlaahgraTentacle implementations (needs testing)
This commit is contained in:
parent
77d0ef942d
commit
b251bc541f
|
@ -0,0 +1,15 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "World/CPatterned.hpp"
|
||||||
|
|
||||||
|
namespace urde::MP1 {
|
||||||
|
class CFlaahgraData {
|
||||||
|
friend class CFlaahgra;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CFlaahgra : public CPatterned {
|
||||||
|
public:
|
||||||
|
DEFINE_PATTERNED(Flaahgra);
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,234 @@
|
||||||
|
#include "CFlaahgraTentacle.hpp"
|
||||||
|
#include "Collision/CCollisionActor.hpp"
|
||||||
|
#include "World/CPlayer.hpp"
|
||||||
|
#include "World/CScriptTrigger.hpp"
|
||||||
|
#include "CStateManager.hpp"
|
||||||
|
#include "TCastTo.hpp"
|
||||||
|
|
||||||
|
namespace urde::MP1 {
|
||||||
|
CFlaahgraTentacle::CFlaahgraTentacle(TUniqueId uid, std::string_view name, const CEntityInfo& info,
|
||||||
|
const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo,
|
||||||
|
const CActorParameters& actParms)
|
||||||
|
: CPatterned(ECharacter::FlaahgraTentacle, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo,
|
||||||
|
EMovementType::Flyer, EColliderType::One, EBodyType::Restricted, actParms, EKnockBackVariant::Large) {
|
||||||
|
x58e_24_ = false;
|
||||||
|
ActorLights()->SetCastShadows(false);
|
||||||
|
x460_knockBackController.SetAutoResetImpulse(false);
|
||||||
|
CreateShadow(true);
|
||||||
|
}
|
||||||
|
void CFlaahgraTentacle::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) {
|
||||||
|
|
||||||
|
switch (msg) {
|
||||||
|
case EScriptObjectMessage::Registered: {
|
||||||
|
x450_bodyController->Activate(mgr);
|
||||||
|
SetupCollisionManager(mgr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EScriptObjectMessage::Deleted: {
|
||||||
|
x56c_collisionManager->Destroy(mgr);
|
||||||
|
if (TCastToPtr<CScriptTrigger> trigger = mgr.ObjectById(x58c_triggerId)) {
|
||||||
|
trigger->SetForceVector(x580_forceVector);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EScriptObjectMessage::Touched: {
|
||||||
|
if (TCastToConstPtr<CCollisionActor> colAct = mgr.GetObjectById(uid)) {
|
||||||
|
if (colAct->GetLastTouchedObject() == mgr.GetPlayer().GetUniqueId() && x420_curDamageRemTime <= 0.f) {
|
||||||
|
mgr.ApplyDamage(mgr.GetPlayer().GetUniqueId(), GetUniqueId(), GetUniqueId(), GetContactDamage(),
|
||||||
|
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {}), {});
|
||||||
|
x420_curDamageRemTime = x424_damageWaitTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EScriptObjectMessage::Play: {
|
||||||
|
x578_ = 0.039999999f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EScriptObjectMessage::Deactivate: {
|
||||||
|
DeathDelete(mgr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EScriptObjectMessage::Open: {
|
||||||
|
ExtractTentacle(mgr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EScriptObjectMessage::Close: {
|
||||||
|
RetractTentacle(mgr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EScriptObjectMessage::InitializedInArea: {
|
||||||
|
SaveBombSlotInfo(mgr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
CPatterned::AcceptScriptMsg(msg, uid, mgr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFlaahgraTentacle::Think(float dt, CStateManager& mgr) {
|
||||||
|
if (!GetActive())
|
||||||
|
return;
|
||||||
|
|
||||||
|
CPatterned::Think(dt, mgr);
|
||||||
|
x56c_collisionManager->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace);
|
||||||
|
|
||||||
|
if (x574_ > 0.f)
|
||||||
|
x574_ -= dt;
|
||||||
|
|
||||||
|
if (x578_ > 0.f)
|
||||||
|
x578_ -= dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFlaahgraTentacle::AddSphereCollisionList(const SSphereJointInfo* sphereJoints, s32 jointCount,
|
||||||
|
std::vector<CJointCollisionDescription>& outJoints) {
|
||||||
|
|
||||||
|
const CAnimData* animData = GetModelData()->GetAnimationData();
|
||||||
|
|
||||||
|
for (u32 i = 0; i < jointCount; ++i) {
|
||||||
|
CSegId segId = animData->GetLocatorSegId(sphereJoints[i].name);
|
||||||
|
if (segId == 0xFF)
|
||||||
|
continue;
|
||||||
|
outJoints.push_back(
|
||||||
|
CJointCollisionDescription::SphereCollision(segId, sphereJoints->radius, sphereJoints->name, 10.f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const SSphereJointInfo CFlaahgraTentacle::skJointList[3] = {{"Arm_8", 2.f}, {"Arm_10", 1.2f}, {"Arm_12", 1.2f}};
|
||||||
|
|
||||||
|
void CFlaahgraTentacle::SetupCollisionManager(CStateManager& mgr) {
|
||||||
|
std::vector<CJointCollisionDescription> jointList;
|
||||||
|
AddSphereCollisionList(skJointList, 3, jointList);
|
||||||
|
x56c_collisionManager.reset(new CCollisionActorManager(mgr, GetUniqueId(), GetAreaIdAlways(), jointList, true));
|
||||||
|
|
||||||
|
for (u32 i = 0; i < x56c_collisionManager->GetNumCollisionActors(); ++i) {
|
||||||
|
const CJointCollisionDescription& desc = x56c_collisionManager->GetCollisionDescFromIndex(i);
|
||||||
|
if (TCastToPtr<CCollisionActor> colAct = mgr.ObjectById(desc.GetCollisionActorId())) {
|
||||||
|
colAct->SetMaterialFilter(CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Player},
|
||||||
|
{EMaterialTypes::Character,
|
||||||
|
EMaterialTypes::CollisionActor,
|
||||||
|
EMaterialTypes::NoStaticCollision,
|
||||||
|
EMaterialTypes::NoPlatformCollision}));
|
||||||
|
colAct->AddMaterial(EMaterialTypes::ScanPassthrough);
|
||||||
|
colAct->SetDamageVulnerability(*GetDamageVulnerability());
|
||||||
|
|
||||||
|
if (x57c_tentacleTipAct == kInvalidUniqueId && desc.GetName() == skpTentacleTip)
|
||||||
|
x57c_tentacleTipAct = desc.GetCollisionActorId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RemoveMaterial(EMaterialTypes::Solid, EMaterialTypes::Target, EMaterialTypes::Orbit, mgr);
|
||||||
|
AddMaterial(EMaterialTypes::Scannable, mgr);
|
||||||
|
|
||||||
|
}
|
||||||
|
zeus::CVector3f CFlaahgraTentacle::GetAimPosition(const CStateManager& mgr, float dt) const {
|
||||||
|
if (TCastToConstPtr<CCollisionActor> colAct = mgr.GetObjectById(x57c_tentacleTipAct))
|
||||||
|
return colAct->GetTranslation();
|
||||||
|
|
||||||
|
return CPatterned::GetAimPosition(mgr, dt);
|
||||||
|
}
|
||||||
|
void CFlaahgraTentacle::ExtractTentacle(CStateManager& mgr) {
|
||||||
|
if (!Inside(mgr, 0.f))
|
||||||
|
return;
|
||||||
|
|
||||||
|
x58e_24_ = true;
|
||||||
|
|
||||||
|
if (TCastToPtr<CScriptTrigger> trigger = mgr.ObjectById(x58c_triggerId)) {
|
||||||
|
trigger->SetForceVector(x580_forceVector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFlaahgraTentacle::RetractTentacle(CStateManager& mgr) {
|
||||||
|
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Crouch);
|
||||||
|
if (TCastToPtr<CScriptTrigger> trigger = mgr.ObjectById(x58c_triggerId)) {
|
||||||
|
trigger->SetForceVector({});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void CFlaahgraTentacle::SaveBombSlotInfo(CStateManager& mgr) {
|
||||||
|
for (const SConnection& conn : GetConnectionList()) {
|
||||||
|
if (conn.x0_state != EScriptObjectState::Modify || conn.x4_msg != EScriptObjectMessage::ToggleActive)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
TUniqueId uid = mgr.GetIdForScript(conn.x8_objId);
|
||||||
|
if (TCastToConstPtr<CScriptTrigger> trigger = mgr.GetObjectById(uid)) {
|
||||||
|
x58c_triggerId = uid;
|
||||||
|
x580_forceVector = trigger->GetForceVector();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CFlaahgraTentacle::ShouldAttack(CStateManager& mgr, float) {
|
||||||
|
if (x578_ > 0.f)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/* FIXME: Double check this */
|
||||||
|
if (x574_ > 0.f || mgr.GetPlayer().IsInWaterMovement())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (TCastToConstPtr<CCollisionActor> colAct = mgr.GetObjectById(x57c_tentacleTipAct)) {
|
||||||
|
float mag = (colAct->GetTranslation().toVec2f() - mgr.GetPlayer().GetTranslation().toVec2f()).magSquared();
|
||||||
|
return mag >= (x2fc_minAttackRange * x2fc_minAttackRange) && mag <= (x300_maxAttackRange * x300_maxAttackRange);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFlaahgraTentacle::Attack(CStateManager& mgr, EStateMsg msg, float) {
|
||||||
|
if (msg == EStateMsg::Activate) {
|
||||||
|
x568_ = 0;
|
||||||
|
} else if (msg == EStateMsg::Update) {
|
||||||
|
if (x568_ == 0) {
|
||||||
|
if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() == pas::EAnimationState::MeleeAttack)
|
||||||
|
x568_ = 2;
|
||||||
|
else
|
||||||
|
x450_bodyController->GetCommandMgr().DeliverCmd(
|
||||||
|
CBCMeleeAttackCmd((x578_ > 0.f ? pas::ESeverity::Zero : pas::ESeverity::One), {}));
|
||||||
|
|
||||||
|
} else if (x568_ == 2 && x450_bodyController->GetBodyStateInfo().GetCurrentStateId() != pas::EAnimationState::MeleeAttack) {
|
||||||
|
x568_ = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (msg == EStateMsg::Deactivate) {
|
||||||
|
x574_ = (x308_attackTimeVariation * mgr.GetActiveRandom()->Float()) + x304_averageAttackTime;
|
||||||
|
x578_ = 0.f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void CFlaahgraTentacle::Retreat(CStateManager& mgr, EStateMsg msg, float) {
|
||||||
|
if (msg == EStateMsg::Update) {
|
||||||
|
if (!x58e_24_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (x330_stateMachineState.GetTime() <= 1.f)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (TCastToPtr<CScriptTrigger> trigger = mgr.ObjectById(x58c_triggerId)) {
|
||||||
|
if (trigger->IsPlayerTriggerProc())
|
||||||
|
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed);
|
||||||
|
}
|
||||||
|
} else if (msg == EStateMsg::Deactivate) {
|
||||||
|
x58e_24_ = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void CFlaahgraTentacle::InActive(CStateManager& mgr, EStateMsg msg, float arg) {
|
||||||
|
if (msg == EStateMsg::Activate) {
|
||||||
|
x570_ = 0.f;
|
||||||
|
} else if (msg == EStateMsg::Update) {
|
||||||
|
if (Inside(mgr, 0.f))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (TCastToPtr<CScriptTrigger> trigger = mgr.ObjectById(x58c_triggerId)) {
|
||||||
|
if (trigger->IsPlayerTriggerProc()) {
|
||||||
|
if (x570_ > 1.f) {
|
||||||
|
RetractTentacle(mgr);
|
||||||
|
ExtractTentacle(mgr);
|
||||||
|
} else
|
||||||
|
x570_ += arg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "World/CPatterned.hpp"
|
||||||
|
#include "Collision/CCollisionActorManager.hpp"
|
||||||
|
|
||||||
|
namespace urde::MP1 {
|
||||||
|
class CFlaahgraTentacle : public CPatterned {
|
||||||
|
static const SSphereJointInfo skJointList[3];
|
||||||
|
static constexpr std::string_view skpTentacleTip = "Arm_12"sv;
|
||||||
|
s32 x568_ = -1;
|
||||||
|
std::unique_ptr<CCollisionActorManager> x56c_collisionManager;
|
||||||
|
float x570_ = 0.f;
|
||||||
|
float x574_ = 0.f;
|
||||||
|
float x578_ = 0.f;
|
||||||
|
TUniqueId x57c_tentacleTipAct = kInvalidUniqueId;
|
||||||
|
zeus::CVector3f x580_forceVector;
|
||||||
|
TUniqueId x58c_triggerId = kInvalidUniqueId;
|
||||||
|
bool x58e_24_ : 1;
|
||||||
|
|
||||||
|
void AddSphereCollisionList(const SSphereJointInfo*, s32, std::vector<CJointCollisionDescription>&);
|
||||||
|
void SetupCollisionManager(CStateManager&);
|
||||||
|
void ExtractTentacle(CStateManager&);
|
||||||
|
void RetractTentacle(CStateManager&);
|
||||||
|
void SaveBombSlotInfo(CStateManager&);
|
||||||
|
public:
|
||||||
|
DEFINE_PATTERNED(FlaahgraTentacle);
|
||||||
|
CFlaahgraTentacle(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, CModelData&&,
|
||||||
|
const CPatternedInfo&, const CActorParameters&);
|
||||||
|
|
||||||
|
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
|
||||||
|
void Think(float, CStateManager&);
|
||||||
|
|
||||||
|
zeus::CVector3f GetAimPosition(const CStateManager&, float) const;
|
||||||
|
|
||||||
|
bool Inside(CStateManager&, float) { return x450_bodyController->GetLocomotionType() == pas::ELocomotionType::Crouch; }
|
||||||
|
bool AnimOver(CStateManager&, float) { return x568_ == 3; }
|
||||||
|
bool ShouldAttack(CStateManager&, float);
|
||||||
|
|
||||||
|
void Dead(CStateManager&, EStateMsg, float) { x450_bodyController->SetLocomotionType(pas::ELocomotionType::Crouch); }
|
||||||
|
void Attack(CStateManager&, EStateMsg, float);
|
||||||
|
void Retreat(CStateManager&, EStateMsg, float);
|
||||||
|
void InActive(CStateManager&, EStateMsg, float);
|
||||||
|
};
|
||||||
|
}
|
|
@ -30,6 +30,8 @@ set(MP1_WORLD_SOURCES
|
||||||
CSeedling.hpp CSeedling.cpp
|
CSeedling.hpp CSeedling.cpp
|
||||||
CRidley.hpp CRidley.cpp
|
CRidley.hpp CRidley.cpp
|
||||||
CPuddleToadGamma.hpp CPuddleToadGamma.cpp
|
CPuddleToadGamma.hpp CPuddleToadGamma.cpp
|
||||||
|
CFlaahgra.hpp CFlaahgra.cpp
|
||||||
|
CFlaahgraTentacle.hpp CFlaahgraTentacle.cpp
|
||||||
CFlaahgraProjectile.hpp CFlaahgraProjectile.cpp
|
CFlaahgraProjectile.hpp CFlaahgraProjectile.cpp
|
||||||
CSpankWeed.hpp CSpankWeed.cpp
|
CSpankWeed.hpp CSpankWeed.cpp
|
||||||
CPuddleSpore.hpp CPuddleSpore.cpp)
|
CPuddleSpore.hpp CPuddleSpore.cpp)
|
||||||
|
|
|
@ -242,12 +242,12 @@ void CScriptEffect::Render(const CStateManager& mgr) const {
|
||||||
*/
|
*/
|
||||||
if (x104_particleSystem && x104_particleSystem->GetParticleCountAll() > 0) {
|
if (x104_particleSystem && x104_particleSystem->GetParticleCountAll() > 0) {
|
||||||
g_NumParticlesRendered += x104_particleSystem->GetParticleCountAll();
|
g_NumParticlesRendered += x104_particleSystem->GetParticleCountAll();
|
||||||
x104_particleSystem->Render(GetActorLights());
|
x104_particleSystem->Render(x138_actorLights.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xf4_electric && xf4_electric->GetParticleCount() > 0) {
|
if (xf4_electric && xf4_electric->GetParticleCount() > 0) {
|
||||||
g_NumParticlesRendered += xf4_electric->GetParticleCount();
|
g_NumParticlesRendered += xf4_electric->GetParticleCount();
|
||||||
xf4_electric->Render(GetActorLights());
|
xf4_electric->Render(x138_actorLights.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,5 +84,10 @@ public:
|
||||||
ETriggerFlags GetTriggerFlags() const { return x12c_flags; }
|
ETriggerFlags GetTriggerFlags() const { return x12c_flags; }
|
||||||
float GetForceMagnitude() const { return x128_forceMagnitude; }
|
float GetForceMagnitude() const { return x128_forceMagnitude; }
|
||||||
const zeus::CVector3f& GetForceVector() const { return x11c_forceField; }
|
const zeus::CVector3f& GetForceVector() const { return x11c_forceField; }
|
||||||
|
void SetForceVector(const zeus::CVector3f& force) {
|
||||||
|
x11c_forceField = force;
|
||||||
|
x128_forceMagnitude = x11c_forceField.magnitude();
|
||||||
|
}
|
||||||
|
bool IsPlayerTriggerProc() const { return x148_28_playerTriggerProc; }
|
||||||
};
|
};
|
||||||
} // namespace urde
|
} // namespace urde
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#include "CScriptActorKeyframe.hpp"
|
#include "CScriptActorKeyframe.hpp"
|
||||||
#include "CScriptActorRotate.hpp"
|
#include "CScriptActorRotate.hpp"
|
||||||
#include "CScriptAiJumpPoint.hpp"
|
#include "CScriptAiJumpPoint.hpp"
|
||||||
|
#include "MP1/World/CFlaahgra.hpp"
|
||||||
|
#include "MP1/World/CFlaahgraTentacle.hpp"
|
||||||
#include "CScriptAreaAttributes.hpp"
|
#include "CScriptAreaAttributes.hpp"
|
||||||
#include "MP1/World/CSeedling.hpp"
|
#include "MP1/World/CSeedling.hpp"
|
||||||
#include "MP1/World/CBurrower.hpp"
|
#include "MP1/World/CBurrower.hpp"
|
||||||
|
@ -2522,7 +2524,26 @@ CEntity* ScriptLoader::LoadAiJumpPoint(CStateManager& mgr, CInputStream& in, int
|
||||||
|
|
||||||
CEntity* ScriptLoader::LoadFlaahgraTentacle(CStateManager& mgr, CInputStream& in, int propCount,
|
CEntity* ScriptLoader::LoadFlaahgraTentacle(CStateManager& mgr, CInputStream& in, int propCount,
|
||||||
const CEntityInfo& info) {
|
const CEntityInfo& info) {
|
||||||
|
|
||||||
|
if (!EnsurePropertyCount(propCount, 6, "FlaahgraTentacle"))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
SScaledActorHead actHead = LoadScaledActorHead(in, mgr);
|
||||||
|
auto pair = CPatternedInfo::HasCorrectParameterCount(in);
|
||||||
|
if (!pair.first)
|
||||||
|
return nullptr;
|
||||||
|
CPatternedInfo pInfo(in, pair.second);
|
||||||
|
CActorParameters actParms = LoadActorParameters(in);
|
||||||
|
|
||||||
|
if (!pInfo.GetAnimationParameters().GetACSFile().IsValid())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
const CAnimationParameters& animParms = pInfo.GetAnimationParameters();
|
||||||
|
CModelData mData(CAnimRes(animParms.GetACSFile(), animParms.GetCharacter(), actHead.x40_scale,
|
||||||
|
animParms.GetInitialAnimation(), true));
|
||||||
|
|
||||||
|
return new MP1::CFlaahgraTentacle(mgr.AllocateUniqueId(), actHead.x0_name, info, actHead.x10_transform,
|
||||||
|
std::move(mData), pInfo, actParms);
|
||||||
}
|
}
|
||||||
|
|
||||||
CEntity* ScriptLoader::LoadRoomAcoustics(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) {
|
CEntity* ScriptLoader::LoadRoomAcoustics(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) {
|
||||||
|
|
Loading…
Reference in New Issue