Merge branch 'master' of ssh://git.axiodl.com:6431/AxioDL/urde

This commit is contained in:
Jack Andersen 2019-06-11 16:05:44 -10:00
commit 0e8e3e906c
15 changed files with 1025 additions and 16 deletions

View File

@ -68,10 +68,12 @@ public:
std::vector<CLight> BuildLightVector() const; std::vector<CLight> BuildLightVector() const;
void ActivateLights(CBooModel& model) const; void ActivateLights(CBooModel& model) const;
void SetCastShadows(bool v) { x298_25_castShadows = v; } 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 SetFindShadowLight(bool v) { x298_27_findShadowLight = v; }
void SetShadowDynamicRangeThreshold(float t) { x2d0_shadowDynamicRangeThreshold = t; } void SetShadowDynamicRangeThreshold(float t) { x2d0_shadowDynamicRangeThreshold = t; }
void SetAmbienceGenerated(bool v) { x298_29_ambienceGenerated = v; } void SetAmbienceGenerated(bool v) { x298_29_ambienceGenerated = v; }
void DisableAreaLights(); void DisableAreaLights();
void SetMaxAreaLights(int l) { x2b8_maxAreaLights = l; }
void SetMaxDynamicLights(int l) { x2bc_maxDynamicLights = l; } void SetMaxDynamicLights(int l) { x2bc_maxDynamicLights = l; }
void SetFindNearestDynamicLights(bool v) { x29a_findNearestDynamicLights = v; } void SetFindNearestDynamicLights(bool v) { x29a_findNearestDynamicLights = v; }
void SetAmbientColor(const zeus::CColor& color) { x288_ambientColor = color; } void SetAmbientColor(const zeus::CColor& color) { x288_ambientColor = color; }

View File

@ -4,6 +4,12 @@
#include "zeus/CAABox.hpp" #include "zeus/CAABox.hpp"
namespace urde { namespace urde {
struct SJointInfo {
const char* from;
const char* to;
float radius;
float separation;
};
struct SOBBJointInfo { struct SOBBJointInfo {
const char* from; const char* from;
const char* to; const char* to;

View File

@ -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

View File

@ -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);
};
}

View File

@ -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;
}
}
}
}
}

View File

@ -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);
};
}

View File

@ -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)

View File

@ -97,8 +97,10 @@ CPatterned::CPatterned(ECharacter character, TUniqueId uid, std::string_view nam
x404_contactDamage.SetRadius(0.f); x404_contactDamage.SetRadius(0.f);
xe6_29_renderParticleDBInside = false; xe6_29_renderParticleDBInside = false;
x402_27_noXrayModel = !x64_modelData->HasModel(CModelData::EWhichModel::XRay); if (x64_modelData) {
BuildBodyController(bodyType); x402_27_noXrayModel = !x64_modelData->HasModel(CModelData::EWhichModel::XRay);
BuildBodyController(bodyType);
}
} }
void CPatterned::Accept(urde::IVisitor& visitor) { visitor.Visit(this); } void CPatterned::Accept(urde::IVisitor& visitor) { visitor.Visit(this); }

View File

@ -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());
} }
} }

View File

@ -40,7 +40,7 @@ CScriptPlatform::CScriptPlatform(
x350_rainGenRate = rainGenRate; x350_rainGenRate = rainGenRate;
x356_24_dead = false; x356_24_dead = false;
; ;
x356_25_notAnimating = false; x356_25_controlledAnimation = false;
x356_26_detectCollision = detectCollision; x356_26_detectCollision = detectCollision;
x356_27_squishedRider = false; x356_27_squishedRider = false;
x356_28_rainSplashes = rainSplashes; x356_28_rainSplashes = rainSplashes;
@ -252,7 +252,7 @@ void CScriptPlatform::Think(float dt, CStateManager& mgr) {
return; return;
if (HasModelData() && GetModelData()->HasAnimData()) { if (HasModelData() && GetModelData()->HasAnimData()) {
if (!x356_25_notAnimating) if (!x356_25_controlledAnimation)
UpdateAnimation(dt, mgr, true); UpdateAnimation(dt, mgr, true);
if (x356_28_rainSplashes && mgr.GetWorld()->GetNeededEnvFx() == EEnvFxType::Rain) { if (x356_28_rainSplashes && mgr.GetWorld()->GetNeededEnvFx() == EEnvFxType::Rain) {
if (HasModelData() && !GetModelData()->IsNull() && mgr.GetEnvFxManager()->IsSplashActive() && if (HasModelData() && !GetModelData()->IsNull() && mgr.GetEnvFxManager()->IsSplashActive() &&

View File

@ -46,7 +46,7 @@ class CScriptPlatform : public CPhysicsActor {
union { union {
struct { struct {
bool x356_24_dead : 1; bool x356_24_dead : 1;
bool x356_25_notAnimating : 1; bool x356_25_controlledAnimation : 1;
bool x356_26_detectCollision : 1; bool x356_26_detectCollision : 1;
bool x356_27_squishedRider : 1; bool x356_27_squishedRider : 1;
bool x356_28_rainSplashes : 1; bool x356_28_rainSplashes : 1;
@ -103,6 +103,7 @@ public:
const CDamageVulnerability* GetDamageVulnerability() const { return &x29c_damageVuln; } const CDamageVulnerability* GetDamageVulnerability() const { return &x29c_damageVuln; }
CHealthInfo* HealthInfo(CStateManager&) { return &x294_health; } 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 void SplashThink(const zeus::CAABox&, const CFluidPlane&, float, CStateManager&) const;
virtual zeus::CQuaternion Move(float, CStateManager&); virtual zeus::CQuaternion Move(float, CStateManager&);

View File

@ -5,6 +5,7 @@
#include "Graphics/CTexture.hpp" #include "Graphics/CTexture.hpp"
#include "World/CActorParameters.hpp" #include "World/CActorParameters.hpp"
#include "World/CPlayer.hpp" #include "World/CPlayer.hpp"
#include "World/CScriptPlatform.hpp"
#include "Weapon/CEnergyProjectile.hpp" #include "Weapon/CEnergyProjectile.hpp"
#include "GameGlobalObjects.hpp" #include "GameGlobalObjects.hpp"
#include "CMemoryCardSys.hpp" #include "CMemoryCardSys.hpp"
@ -38,10 +39,11 @@ CScriptSpecialFunction::CScriptSpecialFunction(TUniqueId uid, std::string_view n
, x170_sfx1(CSfxManager::TranslateSFXID(sId1)) , x170_sfx1(CSfxManager::TranslateSFXID(sId1))
, x172_sfx2(CSfxManager::TranslateSFXID(sId2)) , x172_sfx2(CSfxManager::TranslateSFXID(sId2))
, x174_sfx3(CSfxManager::TranslateSFXID(sId3)) , x174_sfx3(CSfxManager::TranslateSFXID(sId3))
, x184_(0.f)
, x1bc_areaSaveId(aId1) , x1bc_areaSaveId(aId1)
, x1c0_layerIdx(aId2) , x1c0_layerIdx(aId2)
, x1c4_item(itemType) { , x1c4_item(itemType) {
x1e4_26_ = true; x1e4_26_sfx2Played = true;
if (xe8_function == ESpecialFunction::HUDTarget) if (xe8_function == ESpecialFunction::HUDTarget)
x1c8_ = {{zeus::CVector3f(-1.f), zeus::CVector3f(1.f)}}; 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) { void CScriptSpecialFunction::ThinkSpinnerController(float dt, CStateManager& mgr, ESpinnerControllerMode mode) {
bool allowWrap = xec_locatorName.find("AllowWrap") != std::string::npos; bool allowWrap = xec_locatorName.find("AllowWrap") != std::string::npos;
bool noBackward = xec_locatorName.find("NoBackward") != 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) { void CScriptSpecialFunction::ThinkObjectFollowLocator(float, CStateManager& mgr) {

View File

@ -81,13 +81,13 @@ private:
float x138_ = 0.f; float x138_ = 0.f;
zeus::CTransform x13c_ = zeus::CTransform(); zeus::CTransform x13c_ = zeus::CTransform();
float x16c_ = 0.f; float x16c_ = 0.f;
s16 x170_sfx1; u16 x170_sfx1;
s16 x172_sfx2; u16 x172_sfx2;
s16 x174_sfx3; u16 x174_sfx3;
CSfxHandle x178_sfxHandle; CSfxHandle x178_sfxHandle;
u32 x17c_; u32 x17c_;
float x180_ = 0.f; float x180_ = 0.f;
std::vector<float> x184_; TReservedAverage<float, 6> x184_;
float x194_ = 0.f; float x194_ = 0.f;
std::vector<SRingController> x198_ringControllers; std::vector<SRingController> x198_ringControllers;
ERingState x1a8_ringState = ERingState::Stopped; ERingState x1a8_ringState = ERingState::Stopped;
@ -101,8 +101,8 @@ private:
struct { struct {
bool x1e4_24_ : 1; bool x1e4_24_ : 1;
bool x1e4_25_spinnerCanMove : 1; bool x1e4_25_spinnerCanMove : 1;
bool x1e4_26_ : 1; bool x1e4_26_sfx2Played : 1;
bool x1e4_27_ : 1; bool x1e4_27_sfx3Played : 1;
bool x1e4_28_frustumEntered : 1; bool x1e4_28_frustumEntered : 1;
bool x1e4_29_frustumExited : 1; bool x1e4_29_frustumExited : 1;
bool x1e4_30_ : 1; bool x1e4_30_ : 1;

View File

@ -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

View File

@ -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"
@ -2180,7 +2182,32 @@ CEntity* ScriptLoader::LoadPlayerActor(CStateManager& mgr, CInputStream& in, int
} }
CEntity* ScriptLoader::LoadFlaahgra(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) { CEntity* ScriptLoader::LoadFlaahgra(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) {
return nullptr; 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, 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, CEntity* ScriptLoader::LoadFlaahgraTentacle(CStateManager& mgr, CInputStream& in, int propCount,
const CEntityInfo& info) { const CEntityInfo& info) {
return nullptr;
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) { CEntity* ScriptLoader::LoadRoomAcoustics(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) {