mirror of https://github.com/AxioDL/metaforce.git
Merge branch 'master' of ssh://git.axiodl.com:6431/AxioDL/urde
This commit is contained in:
commit
0e8e3e906c
|
@ -68,10 +68,12 @@ public:
|
|||
std::vector<CLight> BuildLightVector() const;
|
||||
void ActivateLights(CBooModel& model) const;
|
||||
void SetCastShadows(bool v) { x298_25_castShadows = v; }
|
||||
void SetHasAreaLights(bool v) { x298_26_hasAreaLights = v; }
|
||||
void SetFindShadowLight(bool v) { x298_27_findShadowLight = v; }
|
||||
void SetShadowDynamicRangeThreshold(float t) { x2d0_shadowDynamicRangeThreshold = t; }
|
||||
void SetAmbienceGenerated(bool v) { x298_29_ambienceGenerated = v; }
|
||||
void DisableAreaLights();
|
||||
void SetMaxAreaLights(int l) { x2b8_maxAreaLights = l; }
|
||||
void SetMaxDynamicLights(int l) { x2bc_maxDynamicLights = l; }
|
||||
void SetFindNearestDynamicLights(bool v) { x29a_findNearestDynamicLights = v; }
|
||||
void SetAmbientColor(const zeus::CColor& color) { x288_ambientColor = color; }
|
||||
|
|
|
@ -4,6 +4,12 @@
|
|||
#include "zeus/CAABox.hpp"
|
||||
|
||||
namespace urde {
|
||||
struct SJointInfo {
|
||||
const char* from;
|
||||
const char* to;
|
||||
float radius;
|
||||
float separation;
|
||||
};
|
||||
struct SOBBJointInfo {
|
||||
const char* from;
|
||||
const char* to;
|
||||
|
|
|
@ -0,0 +1,407 @@
|
|||
#include "CFlaahgra.hpp"
|
||||
#include "CDependencyGroup.hpp"
|
||||
#include "Character/CBoneTracking.hpp"
|
||||
#include "Collision/CCollisionActor.hpp"
|
||||
#include "Collision/CCollisionActorManager.hpp"
|
||||
#include "MP1/World/CFlaahgraProjectile.hpp"
|
||||
#include "World/CActorParameters.hpp"
|
||||
#include "World/CGameArea.hpp"
|
||||
#include "World/CPlayer.hpp"
|
||||
#include "World/CScriptWaypoint.hpp"
|
||||
#include "World/CWorld.hpp"
|
||||
#include "World/ScriptLoader.hpp"
|
||||
#include "GameGlobalObjects.hpp"
|
||||
#include "CSimplePool.hpp"
|
||||
#include "CStateManager.hpp"
|
||||
#include "TCastTo.hpp"
|
||||
|
||||
namespace urde::MP1 {
|
||||
|
||||
const SJointInfo CFlaahgra::skLeftArmJointList[3]{
|
||||
{"L_elbow", "L_blade", 0.6f, 1.f}, {"L_blade", "L_claw", 0.6f, 1.f}, {"L_CLAW_LCTR", "L_CLAW_END_LCTR", 0.6f, 1.f}};
|
||||
|
||||
const SJointInfo CFlaahgra::skRightArmJointList[3]{
|
||||
{"R_elbow", "R_blade", 0.6f, 1.f}, {"R_blade", "R_claw", 0.6f, 1.f}, {"R_CLAW_LCTR", "R_CLAW_END_LCTR", 0.6f, 1.f}};
|
||||
const SSphereJointInfo CFlaahgra::skSphereJointList[5]{
|
||||
{"Head_1", 1.5f}, {"Spine_2", 1.5f}, {"Spine_4", 1.5f}, {"Spine_6", 1.5f}, {"Collar", 1.5f}};
|
||||
|
||||
CFlaahgraData::CFlaahgraData(CInputStream& in)
|
||||
: x0_(in.readFloatBig())
|
||||
, x4_(in.readFloatBig())
|
||||
, x8_(in.readFloatBig())
|
||||
, xc_(in.readFloatBig())
|
||||
, x10_(in)
|
||||
, x78_(in)
|
||||
, x7c_(in)
|
||||
, x98_(in)
|
||||
, x9c_(in)
|
||||
, xb8_(in)
|
||||
, xbc_(in)
|
||||
, xd8_(ScriptLoader::LoadActorParameters(in))
|
||||
, x140_(in.readFloatBig())
|
||||
, x144_(in.readFloatBig())
|
||||
, x148_(in.readFloatBig())
|
||||
, x14c_animationParameters(ScriptLoader::LoadAnimationParameters(in))
|
||||
, x158_(in) {}
|
||||
|
||||
CFlaahgraRenderer::CFlaahgraRenderer(TUniqueId uid, TUniqueId owner, std::string_view name, const CEntityInfo& info,
|
||||
const zeus::CTransform& xf)
|
||||
: CActor(uid, true, name, info, xf, CModelData::CModelDataNull(), CMaterialList(EMaterialTypes::Character),
|
||||
CActorParameters::None(), kInvalidUniqueId)
|
||||
, xe8_owner(owner) {}
|
||||
|
||||
void CFlaahgraRenderer::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const {
|
||||
|
||||
if (const CActor* act = static_cast<const CActor*>(mgr.GetObjectById(xe8_owner))) {
|
||||
if (act->HasModelData() && (act->GetModelData()->HasAnimData() || act->GetModelData()->HasNormalModel()))
|
||||
act->GetModelData()->RenderParticles(frustum);
|
||||
}
|
||||
}
|
||||
void CFlaahgraRenderer::Accept(IVisitor& visitor) { visitor.Visit(this); }
|
||||
|
||||
CFlaahgra::CFlaahgra(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf,
|
||||
const CAnimRes& animRes, const CPatternedInfo& pInfo, const CActorParameters& actParms,
|
||||
const CFlaahgraData& flaahgraData)
|
||||
: CPatterned(ECharacter::Flaahgra, uid, name, EFlavorType::Zero, info, xf, CModelData::CModelDataNull(), pInfo,
|
||||
EMovementType::Flyer, EColliderType::One, EBodyType::Restricted, actParms, EKnockBackVariant::Large)
|
||||
, x56c_(flaahgraData)
|
||||
, x6d4_(g_SimplePool->GetObj({SBIG('PART'), x56c_.xb8_}))
|
||||
, x6dc_(x56c_.x78_, x56c_.x7c_)
|
||||
, x704_(x56c_.x98_, x56c_.x9c_)
|
||||
, x7dc_(GetContactDamage())
|
||||
, x820_(xf.origin)
|
||||
, x8a0_(xf.frontVector())
|
||||
, x8ac_(animRes) {
|
||||
x8e5_29_ = true;
|
||||
x6dc_.Token().Lock();
|
||||
x704_.Token().Lock();
|
||||
x7dc_.SetDamage(0.5f * x7dc_.GetDamage());
|
||||
SetActorLights(actParms.GetLightParameters().MakeActorLights());
|
||||
x90_actorLights->SetCastShadows(false);
|
||||
x90_actorLights->SetMaxAreaLights(2);
|
||||
x90_actorLights->SetHasAreaLights(x90_actorLights->GetMaxAreaLights() > 0);
|
||||
x90_actorLights->SetMaxDynamicLights(1);
|
||||
x460_knockBackController.SetAutoResetImpulse(false);
|
||||
x460_knockBackController.SetEnableLaggedBurnDeath(false);
|
||||
x430_damageColor = skDamageColor;
|
||||
LoadDependencies(x56c_.x158_);
|
||||
/* TODO: Math that makes me go cross eyed */
|
||||
}
|
||||
|
||||
void CFlaahgra::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) {
|
||||
|
||||
switch (msg) {
|
||||
case EScriptObjectMessage::InitializedInArea: {
|
||||
if (!x8e4_25_loading && !x8e4_24_loaded) {
|
||||
const_cast<CGameArea::CPostConstructed*>(mgr.WorldNC()->GetAreaAlways(GetAreaIdAlways())->GetPostConstructed())
|
||||
->x113c_playerActorsLoading++;
|
||||
x8e4_25_loading = true;
|
||||
}
|
||||
|
||||
GetMirrorWaypoints(mgr);
|
||||
break;
|
||||
}
|
||||
case EScriptObjectMessage::Activate: {
|
||||
GatherAssets(mgr);
|
||||
if (x8e5_25_)
|
||||
break;
|
||||
|
||||
SetupCollisionManagers(mgr);
|
||||
x6d0_rendererId = mgr.AllocateUniqueId();
|
||||
mgr.AddObject(new CFlaahgraRenderer(x6d0_rendererId, GetUniqueId(), "Flaahgra Renderer"sv,
|
||||
CEntityInfo(GetAreaIdAlways(), NullConnectionList), GetTransform()));
|
||||
|
||||
//x450_bodyController->SetLocomotionType(pas::ELocomotionType::Crouch);
|
||||
x450_bodyController->Activate(mgr);
|
||||
x8e5_27_ = true;
|
||||
break;
|
||||
}
|
||||
case EScriptObjectMessage::Deleted: {
|
||||
if (!x8e5_27_)
|
||||
break;
|
||||
|
||||
x79c_leftArmCollision->Destroy(mgr);
|
||||
x7a0_rightArmCollision->Destroy(mgr);
|
||||
x7a4_sphereCollision->Destroy(mgr);
|
||||
mgr.FreeScriptObject(x6d0_rendererId);
|
||||
x6d0_rendererId = kInvalidUniqueId;
|
||||
x8e5_27_ = false;
|
||||
break;
|
||||
}
|
||||
case EScriptObjectMessage::Touched: {
|
||||
break;
|
||||
}
|
||||
case EScriptObjectMessage::Damage: {
|
||||
break;
|
||||
}
|
||||
case EScriptObjectMessage::Decrement: {
|
||||
x780_ = 0;
|
||||
break;
|
||||
}
|
||||
case EScriptObjectMessage::Close: {
|
||||
sub801ae980(mgr);
|
||||
break;
|
||||
}
|
||||
case EScriptObjectMessage::Start: {
|
||||
x8e4_31_ = false;
|
||||
break;
|
||||
}
|
||||
case EScriptObjectMessage::Stop: {
|
||||
x8e4_31_ = true;
|
||||
break;
|
||||
}
|
||||
case EScriptObjectMessage::Play: {
|
||||
x7d0_ = 3.f;
|
||||
x8e5_24_ = true;
|
||||
break;
|
||||
}
|
||||
case EScriptObjectMessage::Action: {
|
||||
if (TCastToConstPtr<CGameProjectile>(mgr.GetObjectById(uid)))
|
||||
x7f8_ = x788_;
|
||||
break;
|
||||
}
|
||||
case EScriptObjectMessage::SetToMax: {
|
||||
x7d4_ = 0.f;
|
||||
break;
|
||||
}
|
||||
case EScriptObjectMessage::Reset: {
|
||||
x8e5_28_ = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
CPatterned::AcceptScriptMsg(msg, uid, mgr);
|
||||
}
|
||||
void CFlaahgra::LoadDependencies(CAssetId dgrpId) {
|
||||
if (!dgrpId.IsValid()) {
|
||||
ResetModelDataAndBodyController();
|
||||
x8e4_24_loaded = true;
|
||||
return;
|
||||
}
|
||||
|
||||
x8c8_depGroup = {g_SimplePool->GetObj({SBIG('DGRP'), dgrpId})};
|
||||
x8c8_depGroup->Lock();
|
||||
}
|
||||
|
||||
void CFlaahgra::ResetModelDataAndBodyController() {
|
||||
SetModelData(std::make_unique<CModelData>(x8ac_));
|
||||
_CreateShadow();
|
||||
CreateShadow(true);
|
||||
x94_simpleShadow->SetAlwaysCalculateRadius(false);
|
||||
BuildBodyController(EBodyType::Restricted);
|
||||
x6cc_boneTracking.reset(new CBoneTracking(*GetModelData()->GetAnimationData(), "Head_1"sv, zeus::degToRad(80.f),
|
||||
zeus::degToRad(180.f), EBoneTrackingFlags::None));
|
||||
}
|
||||
void CFlaahgra::GatherAssets(CStateManager& mgr) {
|
||||
if (x8e4_24_loaded)
|
||||
return;
|
||||
|
||||
x8c8_depGroup->GetObj();
|
||||
LoadTokens(mgr);
|
||||
|
||||
if (x8e4_24_loaded)
|
||||
return;
|
||||
|
||||
for (const CToken& tok : x8d4_tokens)
|
||||
tok.GetObj();
|
||||
|
||||
FinalizeLoad(mgr);
|
||||
}
|
||||
|
||||
void CFlaahgra::LoadTokens(CStateManager& mgr) {
|
||||
if (!x8d4_tokens.empty()) {
|
||||
for (const CToken& tok : x8d4_tokens) {
|
||||
if (!tok.IsLoaded())
|
||||
return;
|
||||
}
|
||||
|
||||
FinalizeLoad(mgr);
|
||||
}
|
||||
|
||||
if (!x8c8_depGroup)
|
||||
return;
|
||||
|
||||
TToken<CDependencyGroup> depGroup = *x8c8_depGroup;
|
||||
if (depGroup->GetObjectTagVector().empty()) {
|
||||
FinalizeLoad(mgr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (x8d4_tokens.empty()) {
|
||||
x8d4_tokens.reserve(depGroup->GetObjectTagVector().size());
|
||||
|
||||
for (const auto& tag : depGroup->GetObjectTagVector()) {
|
||||
CToken token = g_SimplePool->GetObj({tag.type, tag.id});
|
||||
token.Lock();
|
||||
x8d4_tokens.push_back(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
void CFlaahgra::FinalizeLoad(CStateManager& mgr) {
|
||||
x8e4_24_loaded = true;
|
||||
if (x8e4_25_loading) {
|
||||
const_cast<CGameArea::CPostConstructed*>(mgr.WorldNC()->GetAreaAlways(GetAreaIdAlways())->GetPostConstructed())
|
||||
->x113c_playerActorsLoading--;
|
||||
x8e4_25_loading = false;
|
||||
}
|
||||
|
||||
ResetModelDataAndBodyController();
|
||||
}
|
||||
|
||||
void CFlaahgra::Think(float dt, CStateManager& mgr) {
|
||||
if (!GetActive())
|
||||
return;
|
||||
|
||||
CPatterned::Think(dt, mgr);
|
||||
x6cc_boneTracking->Update(dt);
|
||||
UpdateCollisionManagers(dt, mgr);
|
||||
x6cc_boneTracking->PreRender(mgr, *ModelData()->AnimationData(), GetTransform(), GetModelData()->GetScale(),
|
||||
*x450_bodyController);
|
||||
UpdateSmallScaleReGrowth(dt);
|
||||
UpdateHealthInfo(mgr);
|
||||
UpdateAimPosition(mgr, dt);
|
||||
x15c_force = {};
|
||||
x168_impulse = {};
|
||||
}
|
||||
|
||||
void CFlaahgra::PreThink(float dt, CStateManager& mgr) {
|
||||
if (!x8e4_24_loaded)
|
||||
LoadTokens(mgr);
|
||||
|
||||
CPatterned::PreThink(dt, mgr);
|
||||
}
|
||||
|
||||
void CFlaahgra::GetMirrorWaypoints(CStateManager& mgr) {
|
||||
x770_mirrorWaypoints.clear();
|
||||
|
||||
for (const SConnection& conn : x20_conns) {
|
||||
if (conn.x0_state != EScriptObjectState::Modify || conn.x4_msg != EScriptObjectMessage::Follow)
|
||||
continue;
|
||||
TUniqueId uid = mgr.GetIdForScript(conn.x8_objId);
|
||||
if (TCastToConstPtr<CScriptWaypoint> wp = mgr.GetObjectById(uid))
|
||||
x770_mirrorWaypoints.push_back(uid);
|
||||
}
|
||||
}
|
||||
|
||||
void CFlaahgra::AddCollisionList(const SJointInfo* joints, int count,
|
||||
std::vector<CJointCollisionDescription>& outJoints) {
|
||||
const CAnimData* animData = GetModelData()->GetAnimationData();
|
||||
for (u32 i = 0; i < count; ++i) {
|
||||
CSegId from = animData->GetLocatorSegId(joints[i].from);
|
||||
CSegId to = animData->GetLocatorSegId(joints[i].to);
|
||||
|
||||
if (to != 0xFF && from != 0xFF) {
|
||||
outJoints.push_back(CJointCollisionDescription::SphereSubdivideCollision(
|
||||
to, from, joints[i].radius, joints[i].separation, CJointCollisionDescription::EOrientationType::One,
|
||||
joints[i].from, 10.f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CFlaahgra::AddSphereCollisionList(const SSphereJointInfo* joints, int count,
|
||||
std::vector<CJointCollisionDescription>& outJoints) {
|
||||
const CAnimData* animData = GetModelData()->GetAnimationData();
|
||||
for (u32 i = 0; i < count; ++i) {
|
||||
CSegId seg = animData->GetLocatorSegId(joints[i].name);
|
||||
if (seg != 0xFF) {
|
||||
outJoints.push_back(CJointCollisionDescription::SphereCollision(seg, joints[i].radius, joints[i].name, 10.f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CFlaahgra::SetupCollisionManagers(CStateManager& mgr) {
|
||||
std::vector<CJointCollisionDescription> leftArmjointList;
|
||||
leftArmjointList.reserve(3);
|
||||
AddCollisionList(skLeftArmJointList, 3, leftArmjointList);
|
||||
x79c_leftArmCollision.reset(
|
||||
new CCollisionActorManager(mgr, GetUniqueId(), GetAreaIdAlways(), leftArmjointList, true));
|
||||
SetMaterialProperties(x79c_leftArmCollision, mgr);
|
||||
std::vector<CJointCollisionDescription> rightArmJointList;
|
||||
rightArmJointList.reserve(3);
|
||||
AddCollisionList(skRightArmJointList, 3, rightArmJointList);
|
||||
x7a0_rightArmCollision.reset(
|
||||
new CCollisionActorManager(mgr, GetUniqueId(), GetAreaIdAlways(), rightArmJointList, true));
|
||||
SetMaterialProperties(x7a0_rightArmCollision, mgr);
|
||||
std::vector<CJointCollisionDescription> sphereJointList;
|
||||
sphereJointList.reserve(3);
|
||||
AddSphereCollisionList(skSphereJointList, 5, sphereJointList);
|
||||
x7a4_sphereCollision.reset(new CCollisionActorManager(mgr, GetUniqueId(), GetAreaIdAlways(), sphereJointList, true));
|
||||
SetMaterialProperties(x7a4_sphereCollision, mgr);
|
||||
}
|
||||
|
||||
void CFlaahgra::sub801ae980(CStateManager& mgr) {
|
||||
HealthInfo(mgr)->SetHP(HealthInfo(mgr)->GetHP() - x56c_.x8_);
|
||||
x7d4_ = x56c_.xc_;
|
||||
x8e4_29_ = true;
|
||||
x430_damageColor = skUnkColor;
|
||||
++x788_;
|
||||
}
|
||||
|
||||
void CFlaahgra::FadeIn(CStateManager& mgr, EStateMsg msg, float) {
|
||||
if (msg != EStateMsg::Activate)
|
||||
return;
|
||||
|
||||
if (HealthInfo(mgr)->GetHP() > 0.f)
|
||||
SendScriptMsgs(EScriptObjectState::Exited, mgr, EScriptObjectMessage::None);
|
||||
|
||||
if (!x8e4_29_)
|
||||
SendScriptMsgs(EScriptObjectState::CloseIn, mgr, EScriptObjectMessage::None);
|
||||
}
|
||||
|
||||
void CFlaahgra::FadeOut(CStateManager& mgr, EStateMsg msg, float) {
|
||||
if (msg != EStateMsg::Activate)
|
||||
return;
|
||||
|
||||
x7a4_sphereCollision->SetActive(mgr, true);
|
||||
x79c_leftArmCollision->SetActive(mgr, true);
|
||||
x7a0_rightArmCollision->SetActive(mgr, true);
|
||||
}
|
||||
void CFlaahgra::UpdateCollisionManagers(float dt, CStateManager& mgr) {
|
||||
x7a4_sphereCollision->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace);
|
||||
x79c_leftArmCollision->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace);
|
||||
x7a0_rightArmCollision->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace);
|
||||
}
|
||||
void CFlaahgra::UpdateSmallScaleReGrowth(float) {}
|
||||
void CFlaahgra::UpdateHealthInfo(CStateManager&) {}
|
||||
void CFlaahgra::UpdateAimPosition(CStateManager&, float) {}
|
||||
void CFlaahgra::SetMaterialProperties(const std::unique_ptr<CCollisionActorManager>& actMgr, CStateManager& mgr) {
|
||||
for (u32 i = 0; i < actMgr->GetNumCollisionActors(); ++i) {
|
||||
TUniqueId uid = actMgr->GetCollisionDescFromIndex(i).GetCollisionActorId();
|
||||
if (CCollisionActor* colAct = static_cast<CCollisionActor*>(mgr.ObjectById(uid))) {
|
||||
colAct->SetMaterialFilter(CMaterialFilter::MakeIncludeExclude(
|
||||
{EMaterialTypes::Player},
|
||||
{EMaterialTypes::Trigger, EMaterialTypes::CollisionActor, EMaterialTypes::Immovable}));
|
||||
colAct->AddMaterial(EMaterialTypes::Trigger, EMaterialTypes::ScanPassthrough, mgr);
|
||||
colAct->SetDamageVulnerability(*GetDamageVulnerability());
|
||||
}
|
||||
}
|
||||
}
|
||||
bool CFlaahgra::ShouldTurn(CStateManager& mgr, float) {
|
||||
zeus::CVector2f posDiff = mgr.GetPlayer().GetTranslation().toVec2f() - GetTranslation().toVec2f();
|
||||
zeus::CVector2f frontVec = x34_transform.frontVector().toVec2f();
|
||||
return zeus::CVector2f::getAngleDiff(frontVec, posDiff) > zeus::degToRad(15.f);
|
||||
}
|
||||
|
||||
void CFlaahgra::TurnAround(CStateManager& mgr, EStateMsg msg, float) {
|
||||
if (msg == EStateMsg::Activate) {
|
||||
x6cc_boneTracking->SetTarget(mgr.GetPlayer().GetUniqueId());
|
||||
x6cc_boneTracking->SetActive(true);
|
||||
x8e5_29_ = false;
|
||||
} else if (msg == EStateMsg::Update) {
|
||||
if (!ShouldTurn(mgr, 0.f))
|
||||
return;
|
||||
|
||||
float dt = 0.f;
|
||||
if (GetModelData()->GetAnimationData()->GetSpeedScale() > 0.f)
|
||||
dt = 1.5f / GetModelData()->GetAnimationData()->GetSpeedScale();
|
||||
|
||||
zeus::CVector3f offset = mgr.GetPlayer().GetAimPosition(mgr, dt) - GetTranslation();
|
||||
if (offset.canBeNormalized()) {
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd({}, offset.normalized(), 1.f));
|
||||
}
|
||||
} else if (msg == EStateMsg::Deactivate) {
|
||||
x6cc_boneTracking->SetActive(false);
|
||||
}
|
||||
}
|
||||
} // namespace urde::MP1
|
|
@ -0,0 +1,163 @@
|
|||
#pragma once
|
||||
|
||||
#include "World/CActorParameters.hpp"
|
||||
#include "World/CAnimationParameters.hpp"
|
||||
#include "World/CPatterned.hpp"
|
||||
#include "Collision/CJointCollisionDescription.hpp"
|
||||
#include "Weapon/CProjectileInfo.hpp"
|
||||
namespace urde {
|
||||
class CCollisionActorManager;
|
||||
class CGenDescription;
|
||||
class CBoneTracking;
|
||||
class CDependencyGroup;
|
||||
}
|
||||
|
||||
namespace urde::MP1 {
|
||||
class CFlaahgraData {
|
||||
friend class CFlaahgra;
|
||||
float x0_;
|
||||
float x4_;
|
||||
float x8_;
|
||||
float xc_;
|
||||
CDamageVulnerability x10_;
|
||||
CAssetId x78_;
|
||||
CDamageInfo x7c_;
|
||||
CAssetId x98_;
|
||||
CDamageInfo x9c_;
|
||||
CAssetId xb8_;
|
||||
CDamageInfo xbc_;
|
||||
CActorParameters xd8_;
|
||||
float x140_;
|
||||
float x144_;
|
||||
float x148_;
|
||||
CAnimationParameters x14c_animationParameters;
|
||||
CAssetId x158_;
|
||||
public:
|
||||
static constexpr u32 GetNumProperties() { return 23; }
|
||||
CFlaahgraData(CInputStream&);
|
||||
|
||||
const CAnimationParameters& GetAnimationParameters() const { return x14c_animationParameters; }
|
||||
};
|
||||
|
||||
class CFlaahgraRenderer : public CActor {
|
||||
TUniqueId xe8_owner;
|
||||
public:
|
||||
CFlaahgraRenderer(TUniqueId, TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&);
|
||||
|
||||
void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const;
|
||||
void Accept(IVisitor&);
|
||||
rstl::optional<zeus::CAABox> GetTouchBounds() const { return {}; }
|
||||
};
|
||||
|
||||
class CFlaahgra : public CPatterned {
|
||||
|
||||
static const SJointInfo skLeftArmJointList[3];
|
||||
static const SJointInfo skRightArmJointList[3];
|
||||
static const SSphereJointInfo skSphereJointList[5];
|
||||
static constexpr zeus::CColor skDamageColor = zeus::CColor(0.5f, 0.5f, 0.f, 1.f);
|
||||
static constexpr zeus::CColor skUnkColor = zeus::CColor(0.5f, 0.f, 0.f, 1.f);
|
||||
s32 x568_ = -1;
|
||||
CFlaahgraData x56c_;
|
||||
std::unique_ptr<CBoneTracking> x6cc_boneTracking; // Used to be an rstl::pair<bool,CBoneTracking>
|
||||
TUniqueId x6d0_rendererId = kInvalidUniqueId;
|
||||
TToken<CGenDescription> x6d4_;
|
||||
CProjectileInfo x6dc_;
|
||||
CProjectileInfo x704_;
|
||||
s32 x72c_ = -1;
|
||||
u32 x730_ = 0;
|
||||
rstl::reserved_vector<TUniqueId, 4> x770_mirrorWaypoints;
|
||||
TUniqueId x77c_ = kInvalidUniqueId;
|
||||
u32 x780_ = 1;
|
||||
u32 x784_ = 1;
|
||||
u32 x788_ = 0;
|
||||
zeus::CVector3f x78c_;
|
||||
s32 x798_ = -1;
|
||||
std::unique_ptr<CCollisionActorManager> x79c_leftArmCollision;
|
||||
std::unique_ptr<CCollisionActorManager> x7a0_rightArmCollision;
|
||||
std::unique_ptr<CCollisionActorManager> x7a4_sphereCollision;
|
||||
s32 x7a8_ = -1;
|
||||
u32 x7ac_ = 1;
|
||||
u32 x7b0_ = 1;
|
||||
s32 x7b4_ = -1;
|
||||
float x7b8_ = 0.f;
|
||||
float x7bc_ = 0.f;
|
||||
float x7c0_ = 0.f;
|
||||
float x7c4_ = 0.f;
|
||||
float x7c8_ = -4.f;
|
||||
float x7cc_ = 0.f;
|
||||
float x7d0_ = 0.f;
|
||||
float x7d4_ = 0.f;
|
||||
float x7d8_ = 0.f;
|
||||
CDamageInfo x7dc_;
|
||||
u32 x7f8_ = 0;
|
||||
u32 x7fc_ = 0;
|
||||
TUniqueId x80c_ = kInvalidUniqueId;
|
||||
float x810_ = 0.f;
|
||||
float x814_ = 0.f;
|
||||
float x818_ = 0.f;
|
||||
zeus::CVector3f x820_;
|
||||
u32 x82c_ = 0;
|
||||
u32 x860_ = 0;
|
||||
zeus::CVector3f x894_;
|
||||
zeus::CVector3f x8a0_;
|
||||
CAnimRes x8ac_;
|
||||
rstl::optional<TToken<CDependencyGroup>> x8c8_depGroup;
|
||||
bool x8d0_ = false;
|
||||
std::vector<CToken> x8d4_tokens;
|
||||
union {
|
||||
struct {
|
||||
bool x8e4_24_loaded : 1;
|
||||
bool x8e4_25_loading : 1;
|
||||
bool x8e4_26_ : 1;
|
||||
bool x8e4_27_ : 1;
|
||||
bool x8e4_28_ : 1;
|
||||
bool x8e4_29_ : 1;
|
||||
bool x8e4_30_ : 1;
|
||||
bool x8e4_31_ : 1;
|
||||
bool x8e5_24_ : 1;
|
||||
bool x8e5_25_ : 1;
|
||||
bool x8e5_26_ : 1;
|
||||
bool x8e5_27_ : 1;
|
||||
bool x8e5_28_ : 1;
|
||||
bool x8e5_29_ : 1;
|
||||
bool x8e5_30_ : 1;
|
||||
};
|
||||
u32 _dummy = 0;
|
||||
};
|
||||
|
||||
|
||||
void LoadDependencies(CAssetId);
|
||||
void ResetModelDataAndBodyController();
|
||||
void GatherAssets(CStateManager& mgr);
|
||||
void LoadTokens(CStateManager& mgr);
|
||||
void FinalizeLoad(CStateManager& mgr);
|
||||
void GetMirrorWaypoints(CStateManager& mgr);
|
||||
void AddCollisionList(const SJointInfo*, int, std::vector<CJointCollisionDescription>&);
|
||||
void AddSphereCollisionList(const SSphereJointInfo*, int, std::vector<CJointCollisionDescription>&);
|
||||
void SetupCollisionManagers(CStateManager&);
|
||||
void sub801ae980(CStateManager&);
|
||||
void UpdateCollisionManagers(float, CStateManager&);
|
||||
void UpdateSmallScaleReGrowth(float);
|
||||
void UpdateHealthInfo(CStateManager&);
|
||||
void UpdateAimPosition(CStateManager&, float);
|
||||
void SetMaterialProperties(const std::unique_ptr<CCollisionActorManager>&, CStateManager&);
|
||||
|
||||
public:
|
||||
DEFINE_PATTERNED(Flaahgra);
|
||||
CFlaahgra(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, const CAnimRes&,
|
||||
const CPatternedInfo&, const CActorParameters&, const CFlaahgraData&);
|
||||
|
||||
void Think(float, CStateManager&);
|
||||
void PreThink(float, CStateManager&);
|
||||
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
|
||||
bool CanRenderUnsorted(const CStateManager&) const { return true; }
|
||||
zeus::CVector3f GetAimPosition(const CStateManager&, float) const { return x820_; }
|
||||
|
||||
bool AnimOver(CStateManager&, float) { return x568_ == 4; }
|
||||
bool ShouldTurn(CStateManager&, float);
|
||||
|
||||
void FadeIn(CStateManager&, EStateMsg, float);
|
||||
void FadeOut(CStateManager&, EStateMsg, float);
|
||||
void TurnAround(CStateManager&, EStateMsg, float);
|
||||
};
|
||||
}
|
|
@ -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(false);
|
||||
}
|
||||
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
|
||||
CRidley.hpp CRidley.cpp
|
||||
CPuddleToadGamma.hpp CPuddleToadGamma.cpp
|
||||
CFlaahgra.hpp CFlaahgra.cpp
|
||||
CFlaahgraTentacle.hpp CFlaahgraTentacle.cpp
|
||||
CFlaahgraProjectile.hpp CFlaahgraProjectile.cpp
|
||||
CSpankWeed.hpp CSpankWeed.cpp
|
||||
CPuddleSpore.hpp CPuddleSpore.cpp)
|
||||
|
|
|
@ -97,8 +97,10 @@ CPatterned::CPatterned(ECharacter character, TUniqueId uid, std::string_view nam
|
|||
x404_contactDamage.SetRadius(0.f);
|
||||
|
||||
xe6_29_renderParticleDBInside = false;
|
||||
if (x64_modelData) {
|
||||
x402_27_noXrayModel = !x64_modelData->HasModel(CModelData::EWhichModel::XRay);
|
||||
BuildBodyController(bodyType);
|
||||
}
|
||||
}
|
||||
|
||||
void CPatterned::Accept(urde::IVisitor& visitor) { visitor.Visit(this); }
|
||||
|
|
|
@ -242,12 +242,12 @@ void CScriptEffect::Render(const CStateManager& mgr) const {
|
|||
*/
|
||||
if (x104_particleSystem && x104_particleSystem->GetParticleCountAll() > 0) {
|
||||
g_NumParticlesRendered += x104_particleSystem->GetParticleCountAll();
|
||||
x104_particleSystem->Render(GetActorLights());
|
||||
x104_particleSystem->Render(x138_actorLights.get());
|
||||
}
|
||||
|
||||
if (xf4_electric && xf4_electric->GetParticleCount() > 0) {
|
||||
g_NumParticlesRendered += xf4_electric->GetParticleCount();
|
||||
xf4_electric->Render(GetActorLights());
|
||||
xf4_electric->Render(x138_actorLights.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ CScriptPlatform::CScriptPlatform(
|
|||
x350_rainGenRate = rainGenRate;
|
||||
x356_24_dead = false;
|
||||
;
|
||||
x356_25_notAnimating = false;
|
||||
x356_25_controlledAnimation = false;
|
||||
x356_26_detectCollision = detectCollision;
|
||||
x356_27_squishedRider = false;
|
||||
x356_28_rainSplashes = rainSplashes;
|
||||
|
@ -252,7 +252,7 @@ void CScriptPlatform::Think(float dt, CStateManager& mgr) {
|
|||
return;
|
||||
|
||||
if (HasModelData() && GetModelData()->HasAnimData()) {
|
||||
if (!x356_25_notAnimating)
|
||||
if (!x356_25_controlledAnimation)
|
||||
UpdateAnimation(dt, mgr, true);
|
||||
if (x356_28_rainSplashes && mgr.GetWorld()->GetNeededEnvFx() == EEnvFxType::Rain) {
|
||||
if (HasModelData() && !GetModelData()->IsNull() && mgr.GetEnvFxManager()->IsSplashActive() &&
|
||||
|
|
|
@ -46,7 +46,7 @@ class CScriptPlatform : public CPhysicsActor {
|
|||
union {
|
||||
struct {
|
||||
bool x356_24_dead : 1;
|
||||
bool x356_25_notAnimating : 1;
|
||||
bool x356_25_controlledAnimation : 1;
|
||||
bool x356_26_detectCollision : 1;
|
||||
bool x356_27_squishedRider : 1;
|
||||
bool x356_28_rainSplashes : 1;
|
||||
|
@ -103,6 +103,7 @@ public:
|
|||
|
||||
const CDamageVulnerability* GetDamageVulnerability() const { return &x29c_damageVuln; }
|
||||
CHealthInfo* HealthInfo(CStateManager&) { return &x294_health; }
|
||||
void SetControlledAnimation(bool controlled) { x356_25_controlledAnimation = controlled; }
|
||||
|
||||
virtual void SplashThink(const zeus::CAABox&, const CFluidPlane&, float, CStateManager&) const;
|
||||
virtual zeus::CQuaternion Move(float, CStateManager&);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "Graphics/CTexture.hpp"
|
||||
#include "World/CActorParameters.hpp"
|
||||
#include "World/CPlayer.hpp"
|
||||
#include "World/CScriptPlatform.hpp"
|
||||
#include "Weapon/CEnergyProjectile.hpp"
|
||||
#include "GameGlobalObjects.hpp"
|
||||
#include "CMemoryCardSys.hpp"
|
||||
|
@ -38,10 +39,11 @@ CScriptSpecialFunction::CScriptSpecialFunction(TUniqueId uid, std::string_view n
|
|||
, x170_sfx1(CSfxManager::TranslateSFXID(sId1))
|
||||
, x172_sfx2(CSfxManager::TranslateSFXID(sId2))
|
||||
, x174_sfx3(CSfxManager::TranslateSFXID(sId3))
|
||||
, x184_(0.f)
|
||||
, x1bc_areaSaveId(aId1)
|
||||
, x1c0_layerIdx(aId2)
|
||||
, x1c4_item(itemType) {
|
||||
x1e4_26_ = true;
|
||||
x1e4_26_sfx2Played = true;
|
||||
if (xe8_function == ESpecialFunction::HUDTarget)
|
||||
x1c8_ = {{zeus::CVector3f(-1.f), zeus::CVector3f(1.f)}};
|
||||
}
|
||||
|
@ -565,7 +567,102 @@ void CScriptSpecialFunction::ThinkPlayerFollowLocator(float, CStateManager& mgr)
|
|||
void CScriptSpecialFunction::ThinkSpinnerController(float dt, CStateManager& mgr, ESpinnerControllerMode mode) {
|
||||
bool allowWrap = xec_locatorName.find("AllowWrap") != std::string::npos;
|
||||
bool noBackward = xec_locatorName.find("NoBackward") != std::string::npos;
|
||||
float pointOneByDt = 0.1f * dt;
|
||||
float twoByDt = 2.f * dt;
|
||||
|
||||
for (const SConnection& conn : x20_conns) {
|
||||
if (conn.x0_state != EScriptObjectState::Play || conn.x4_msg != EScriptObjectMessage::Activate)
|
||||
continue;
|
||||
|
||||
auto search = mgr.GetIdListForScript(conn.x8_objId);
|
||||
for (auto it = search.first; it != search.second; ++it) {
|
||||
if (TCastToPtr<CScriptPlatform> plat = mgr.ObjectById((*it).second)) {
|
||||
if (plat->HasModelData() && plat->GetModelData()->HasAnimData()) {
|
||||
plat->SetControlledAnimation(true);
|
||||
if (!x1e4_24_) {
|
||||
x13c_ = plat->GetTransform();
|
||||
x1e4_24_ = true;
|
||||
}
|
||||
|
||||
float f28 = x138_;
|
||||
float f29 = pointOneByDt * x100_float2;
|
||||
|
||||
if (mode == ESpinnerControllerMode::Zero) {
|
||||
if (x1e4_25_spinnerCanMove) {
|
||||
CPlayer& pl = mgr.GetPlayer();
|
||||
zeus::CVector3f angVel = pl.GetAngularVelocityOR().getVector();
|
||||
float mag = 0.f;
|
||||
if (angVel.canBeNormalized())
|
||||
mag = angVel.magnitude();
|
||||
|
||||
float spinImpulse = (pl.GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed ? 0.025f * mag
|
||||
: 0.f);
|
||||
if (spinImpulse > x180_)
|
||||
SendScriptMsgs(EScriptObjectState::Play, mgr, EScriptObjectMessage::None);
|
||||
|
||||
x180_ = spinImpulse;
|
||||
x138_ += 0.01f * spinImpulse * xfc_float1;
|
||||
|
||||
if (!noBackward)
|
||||
x138_ -= f29;
|
||||
} else if (!noBackward) {
|
||||
x138_ = twoByDt - f28;
|
||||
}
|
||||
} else if (mode == ESpinnerControllerMode::One) {
|
||||
x138_ = (0.1f * x16c_) * xfc_float1 + f28;
|
||||
|
||||
if (!noBackward) {
|
||||
x138_ -= f29;
|
||||
|
||||
if (std::fabs(x16c_) < dt)
|
||||
x16c_ = 0.f;
|
||||
else
|
||||
x16c_ += (dt * (x16c_ < 0 ? -1.f : 1.f));
|
||||
}
|
||||
|
||||
if (allowWrap) {
|
||||
x138_ = std::fmod(x138_, 1.f);
|
||||
if (x138_ < 0.f)
|
||||
x138_ += 1.f;
|
||||
} else {
|
||||
x138_ = zeus::clamp(0.f, x138_, 1.f);
|
||||
}
|
||||
|
||||
f28 = f28 - x138_;
|
||||
bool r23 = true;
|
||||
if (zeus::close_enough(1.f, x138_, FLT_EPSILON)) {
|
||||
if (!x1e4_27_sfx3Played) {
|
||||
if (x174_sfx3 != 0xFFFF)
|
||||
CSfxManager::AddEmitter(x174_sfx3, GetTranslation(), {}, true, false, 0x7F, kInvalidAreaId);
|
||||
|
||||
x1e4_27_sfx3Played = true;
|
||||
}
|
||||
|
||||
SendScriptMsgs(EScriptObjectState::MaxReached, mgr, EScriptObjectMessage::None);
|
||||
r23 = false;
|
||||
} else
|
||||
x1e4_27_sfx3Played = false;
|
||||
|
||||
if (zeus::close_enough(0.f, x138_, FLT_EPSILON)) {
|
||||
if (!x1e4_26_sfx2Played) {
|
||||
if (x172_sfx2 != 0xFFFF)
|
||||
CSfxManager::AddEmitter(x172_sfx2, GetTranslation(), {}, true, false, 0x7F, kInvalidAreaId);
|
||||
|
||||
x1e4_26_sfx2Played = true;
|
||||
}
|
||||
|
||||
SendScriptMsgs(EScriptObjectState::Zero, mgr, EScriptObjectMessage::None);
|
||||
r23 = false;
|
||||
} else
|
||||
x1e4_26_sfx2Played = false;
|
||||
}
|
||||
|
||||
auto average = x184_.GetAverage();
|
||||
/* TODO Finish */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CScriptSpecialFunction::ThinkObjectFollowLocator(float, CStateManager& mgr) {
|
||||
|
|
|
@ -81,13 +81,13 @@ private:
|
|||
float x138_ = 0.f;
|
||||
zeus::CTransform x13c_ = zeus::CTransform();
|
||||
float x16c_ = 0.f;
|
||||
s16 x170_sfx1;
|
||||
s16 x172_sfx2;
|
||||
s16 x174_sfx3;
|
||||
u16 x170_sfx1;
|
||||
u16 x172_sfx2;
|
||||
u16 x174_sfx3;
|
||||
CSfxHandle x178_sfxHandle;
|
||||
u32 x17c_;
|
||||
float x180_ = 0.f;
|
||||
std::vector<float> x184_;
|
||||
TReservedAverage<float, 6> x184_;
|
||||
float x194_ = 0.f;
|
||||
std::vector<SRingController> x198_ringControllers;
|
||||
ERingState x1a8_ringState = ERingState::Stopped;
|
||||
|
@ -101,8 +101,8 @@ private:
|
|||
struct {
|
||||
bool x1e4_24_ : 1;
|
||||
bool x1e4_25_spinnerCanMove : 1;
|
||||
bool x1e4_26_ : 1;
|
||||
bool x1e4_27_ : 1;
|
||||
bool x1e4_26_sfx2Played : 1;
|
||||
bool x1e4_27_sfx3Played : 1;
|
||||
bool x1e4_28_frustumEntered : 1;
|
||||
bool x1e4_29_frustumExited : 1;
|
||||
bool x1e4_30_ : 1;
|
||||
|
|
|
@ -84,5 +84,10 @@ public:
|
|||
ETriggerFlags GetTriggerFlags() const { return x12c_flags; }
|
||||
float GetForceMagnitude() const { return x128_forceMagnitude; }
|
||||
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
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include "CScriptActorKeyframe.hpp"
|
||||
#include "CScriptActorRotate.hpp"
|
||||
#include "CScriptAiJumpPoint.hpp"
|
||||
#include "MP1/World/CFlaahgra.hpp"
|
||||
#include "MP1/World/CFlaahgraTentacle.hpp"
|
||||
#include "CScriptAreaAttributes.hpp"
|
||||
#include "MP1/World/CSeedling.hpp"
|
||||
#include "MP1/World/CBurrower.hpp"
|
||||
|
@ -2180,7 +2182,32 @@ CEntity* ScriptLoader::LoadPlayerActor(CStateManager& mgr, CInputStream& in, int
|
|||
}
|
||||
|
||||
CEntity* ScriptLoader::LoadFlaahgra(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) {
|
||||
if (!EnsurePropertyCount(propCount, MP1::CFlaahgraData::GetNumProperties(), "Flaahgra"))
|
||||
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);
|
||||
MP1::CFlaahgraData flaahgraData(in);
|
||||
|
||||
CAnimRes animRes(pInfo.GetAnimationParameters().GetACSFile(), pInfo.GetAnimationParameters().GetCharacter(),
|
||||
actHead.x40_scale, pInfo.GetAnimationParameters().GetInitialAnimation(), true);
|
||||
|
||||
if (!pInfo.GetAnimationParameters().GetACSFile().IsValid()) {
|
||||
animRes = CAnimRes(flaahgraData.GetAnimationParameters().GetACSFile(),
|
||||
flaahgraData.GetAnimationParameters().GetCharacter(), actHead.x40_scale,
|
||||
flaahgraData.GetAnimationParameters().GetInitialAnimation(), true);
|
||||
}
|
||||
|
||||
if (!animRes.GetId().IsValid())
|
||||
return nullptr;
|
||||
|
||||
return new MP1::CFlaahgra(mgr.AllocateUniqueId(), actHead.x0_name, info, actHead.x10_transform, animRes, pInfo,
|
||||
actParms, flaahgraData);
|
||||
}
|
||||
|
||||
CEntity* ScriptLoader::LoadAreaAttributes(CStateManager& mgr, CInputStream& in, int propCount,
|
||||
|
@ -2522,7 +2549,26 @@ CEntity* ScriptLoader::LoadAiJumpPoint(CStateManager& mgr, CInputStream& in, int
|
|||
|
||||
CEntity* ScriptLoader::LoadFlaahgraTentacle(CStateManager& mgr, CInputStream& in, int propCount,
|
||||
const CEntityInfo& info) {
|
||||
|
||||
if (!EnsurePropertyCount(propCount, 6, "FlaahgraTentacle"))
|
||||
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) {
|
||||
|
|
Loading…
Reference in New Issue