Initial CParasite implementation

This commit is contained in:
Phillip Stephens 2018-09-16 16:22:35 -07:00
parent ac33e46590
commit 02d54fd5ca
20 changed files with 564 additions and 78 deletions

View File

@ -1734,7 +1734,7 @@ bool CStateManager::ApplyLocalDamage(const zeus::CVector3f& vec1, const zeus::CV
hInfo->SetHP(newHp);
bool significant = std::fabs(newHp - hInfo->GetHP()) >= 0.00001;
if (player)
if (player && GetPlayerState()->CanTakeDamage())
{
player->TakeDamage(significant, vec1, mulDam, weapMode.GetType(), *this);
if (newHp <= 0.f)

View File

@ -237,7 +237,7 @@ bool CAnimData::IsAdditiveAnimationActive(u32 idx) const
return search->second.IsActive();
}
void CAnimData::DelAdditiveAnimation(u32 idx)
void CAnimData::DelAdditiveAnimation(s32 idx)
{
u32 animIdx = xc_charInfo.GetAnimationIndex(idx);
for (std::pair<u32, CAdditiveAnimPlayback>& anim : x434_additiveAnims)
@ -252,7 +252,7 @@ void CAnimData::DelAdditiveAnimation(u32 idx)
}
}
void CAnimData::AddAdditiveAnimation(u32 idx, float weight, bool active, bool fadeOut)
void CAnimData::AddAdditiveAnimation(s32 idx, float weight, bool active, bool fadeOut)
{
u32 animIdx = xc_charInfo.GetAnimationIndex(idx);
for (std::pair<u32, CAdditiveAnimPlayback>& anim : x434_additiveAnims)

View File

@ -176,8 +176,8 @@ public:
const std::shared_ptr<CAnimTreeNode>& GetRootAnimationTree() const { return x1f8_animRoot; }
const std::shared_ptr<CAnimTreeNode>& GetAdditiveAnimationTree(u32) const;
bool IsAdditiveAnimationActive(u32) const;
void DelAdditiveAnimation(u32);
void AddAdditiveAnimation(u32, float, bool, bool);
void DelAdditiveAnimation(s32);
void AddAdditiveAnimation(s32, float, bool, bool);
float GetAdditiveAnimationWeight(u32 idx) const;
std::shared_ptr<CAnimationManager> GetAnimationManager();
const CCharacterInfo& GetCharacterInfo() const { return xc_charInfo; }

View File

@ -63,6 +63,7 @@ public:
const CBodyStateInfo& GetBodyStateInfo() const { return x2a4_bodyStateInfo; }
CBodyStateInfo& BodyStateInfo() { return x2a4_bodyStateInfo; }
float GetTurnSpeed() const { return x2fc_turnSpeed; }
void SetLocomotionType(pas::ELocomotionType type) { x2ec_locomotionType = type; }
pas::ELocomotionType GetLocomotionType() const { return x2ec_locomotionType; }
CActor& GetOwner() const { return x0_actor; }
bool IsAnimationOver() const { return x300_24_animationOver; }
@ -106,6 +107,7 @@ public:
EBodyType GetBodyType() const { return x2f4_bodyType; }
bool HasBeenFrozen() const { return x300_27_hasBeenFrozen; }
float GetRestrictedFlyerMoveSpeed() const { return x330_restrictedFlyerMoveSpeed; }
bool GetActive() const { return x300_25_active; }
};
}

View File

@ -29,15 +29,15 @@ CCharacterInfo::CParticleResData::CParticleResData(CInputStream& in, u16 tableCo
}
}
static std::vector<std::pair<u32, std::pair<std::string, std::string>>>
static std::vector<std::pair<s32, std::pair<std::string, std::string>>>
MakeAnimInfoVector(CInputStream& in)
{
std::vector<std::pair<u32, std::pair<std::string, std::string>>> ret;
std::vector<std::pair<s32, std::pair<std::string, std::string>>> ret;
u32 animInfoCount = in.readUint32Big();
ret.reserve(animInfoCount);
for (u32 i=0 ; i<animInfoCount ; ++i)
{
u32 idx = in.readUint32Big();
s32 idx = in.readInt32Big();
std::string a = in.readString();
std::string b = in.readString();
ret.emplace_back(idx, std::make_pair(a, b));
@ -99,4 +99,15 @@ CCharacterInfo::CCharacterInfo(CInputStream& in)
}
}
const s32 CCharacterInfo::GetAnimationIndex(std::string_view name) const
{
for (const auto& pair : x20_animInfo)
{
if (pair.second.second.compare(name.data()) == 0)
return pair.first;
}
return -1;
}
}

View File

@ -29,7 +29,7 @@ private:
CAssetId x14_cmdl;
CAssetId x18_cskr;
CAssetId x1c_cinf;
std::vector<std::pair<u32, std::pair<std::string, std::string>>> x20_animInfo;
std::vector<std::pair<s32, std::pair<std::string, std::string>>> x20_animInfo;
CPASDatabase x30_pasDatabase;
CParticleResData x44_partRes;
u32 x84_unk;
@ -61,6 +61,8 @@ public:
const CParticleResData& GetParticleResData() const { return x44_partRes; }
s32 GetAnimationIndex(s32 idx) const { return xb0_animIdxs.at(idx); }
const CPASDatabase& GetPASDatabase() const { return x30_pasDatabase; }
const s32 GetAnimationIndex(std::string_view) const;
};
}

View File

@ -35,4 +35,15 @@ CSteeringBehaviors::ProjectOrbitalPosition(const zeus::CVector3f& pos, const zeu
return usePos;
}
bool CSteeringBehaviors::SolveQuadratic(float f30, float f31, float f3, float f4, float& out1, float& out2)
{
float f1 = f31 * f31 - 4.f * f30 * f3;
if (f1 > FLT_EPSILON && std::fabs(f1) < FLT_EPSILON)
return false;
out1 = -f31 + std::sqrt(f1) / 2.f * f30;
out2 = -f31 - std::sqrt(f1) / 2.f * f30;
return true;
}
}

View File

@ -13,6 +13,7 @@ class CSteeringBehaviors
public:
static zeus::CVector3f ProjectOrbitalPosition(const zeus::CVector3f& pos, const zeus::CVector3f& vel,
const zeus::CVector3f& orbitPoint, float dt, float preThinkDt);
static bool SolveQuadratic(float, float, float, float, float&, float&);
};
}

View File

@ -1,19 +1,270 @@
#include "CParasite.hpp"
#include "Character/CModelData.hpp"
#include "TCastTo.hpp"
#include "World/CActorParameters.hpp"
#include "World/CPatternedInfo.hpp"
#include "World/CWorld.hpp"
#include "World/CGameArea.hpp"
#include "World/CPlayer.hpp"
#include "CStateManager.hpp"
#include "TCastTo.hpp"
namespace urde::MP1 {
CParasite::CParasite(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo &info, const zeus::CTransform &xf,
CModelData &&mData, const CPatternedInfo &pInfo, u32, float, float, float, float, float, float, float, float,
float, float, float, float, float, float, float, float, float, float, bool, u32, const CDamageVulnerability &,
const CParasiteInfo &, u16, u16, u16, u32, u32, float, const CActorParameters &aParams)
: CWallWalker(ECharacter::Parasite, uid, name, flavor, info, xf, std::move(mData), pInfo, EMovementType::Ground, EColliderType::One, EBodyType::WallWalker,
aParams, -1, 0)
namespace urde::MP1
{
const float CParasite::flt_805A8FB0 = 2.f * std::sqrt(2.5f / 24.525002f);
const float CParasite::skAttackVelocity = 15.f / 2.f * (std::sqrt(2.5f / 24.525002f));
short CParasite::word_805A8FC0 = 0;
const float CParasite::flt_805A8FB8 = 2.f * std::sqrt(2.5f / 24.525002f);
const float CParasite::skRetreatVelocity = 3.f / 2.f * std::sqrt(2.5f / 24.525002f);
CParasite::CParasite(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo &info,
const zeus::CTransform &xf, CModelData &&mData, const CPatternedInfo &pInfo, EBodyType bodyType,
float f1, float f2, float f3, float f4, float f5, float f6, float f7, float f8, float f9,
float f10, float f11, float f12, float f13, float f14, float f15, float f16, float f17, float f18,
bool b1, u32 w1, const CDamageVulnerability& dVuln,const CDamageInfo& parInfo, u16 sfxId1,
u16 sfxId2, u16 sfxId3, u32 w2, u32 w3, float f19, const CActorParameters &aParams)
: CWallWalker(ECharacter::Parasite, uid, name, flavor, info, xf, std::move(mData), pInfo, EMovementType::Flyer,
EColliderType::Zero, bodyType, aParams, f7, f4, 0, f2, w1, f17, b1)
, x64c_(dVuln)
, x6b4_(parInfo)
, x6d0_(f1)
, x6d4_(f3)
, x6dc_(f5)
, x6e0_(f6)
, x6e4_(f8)
, x6e8_(f9)
, x6ec_(f10)
, x6f0_(f11)
, x6f4_(f12)
, x6f8_(f13)
, x6fc_(f14)
, x700_(f15)
, x704_(f16)
, x708_(pInfo.GetHeight() * 0.5f)
, x710_(f18)
, x714_(f19)
, x73c_(CSfxManager::TranslateSFXID(sfxId1))
, x73e_(CSfxManager::TranslateSFXID(sfxId2))
, x740_(CSfxManager::TranslateSFXID(sfxId3))
{
x742_28_ = true;
x742_30_ = true;
switch(x5d0_)
{
case 2:
//x460_.x81_25_ = false;
case 1:
//x460_.sub80233d64(false);
break;
case 3:
default:
break;
}
if (x5d0_ == 1)
{
}
}
void CParasite::Accept(IVisitor &visitor) { visitor.Visit(this); }
void CParasite::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr)
{
CPatterned::AcceptScriptMsg(msg, uid, mgr);
if (msg == EScriptObjectMessage::Registered)
{
x450_bodyController->Activate(mgr);
/* TODO: Finish 8015A0E8*/
}
else if (msg == EScriptObjectMessage::Deleted)
{
//mgr.xf54_.sub80125d88(GetUniqueId());
if (x5d0_ != 3)
DestroyActorManager(mgr);
}
else if (msg == EScriptObjectMessage::Jumped && x742_25_)
{
UpdateJumpVelocity();
x742_25_ = false;
}
else if (msg == EScriptObjectMessage::Activate)
{
x5d6_27_ = false;
if (x5d0_ != 0)
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk);
}
else if (msg == EScriptObjectMessage::SuspendedMove)
{
}
}
void CParasite::PreThink(float dt, CStateManager& mgr)
{
CWallWalker::PreThink(dt, mgr);
x743_26_ = false;
}
void CParasite::Think(float dt, CStateManager& mgr)
{
if (!GetActive())
return;
++x5d4_;
if (x5d0_ == 3)
UpdateCollisionActors(mgr);
x5d6_26_ = false;
CGameArea* area = mgr.WorldNC()->GetArea(GetAreaIdAlways());
CGameArea::EOcclusionState r6 = CGameArea::EOcclusionState::Occluded;
if (area->IsPostConstructed())
r6 = area->GetPostConstructed()->x10dc_occlusionState;
if (r6 != CGameArea::EOcclusionState::Visible)
x5d6_26_ = true;
if (!x5d6_26_)
{
zeus::CVector3f plVec = mgr.GetPlayer().GetTranslation();
float distance = (GetTranslation() - plVec).magnitude() ;
if (distance > x5c4_)
{
CRayCastResult res = mgr.RayStaticIntersection(plVec, (GetTranslation() - plVec).normalized(), distance,
CMaterialFilter::skPassEverything);
if (res.IsValid())
x5d6_26_ = true;
}
}
if (x5d6_26_)
{
xf8_24_movable = x5d6_26_;
return;
}
xf8_24_movable = !xf8_24_movable;
if (!x5d6_27_)
{
if (x450_bodyController->IsFrozen())
{
if ((GetTranslation() - x614_).magSquared() < 0.3f /* <- Used to be a static variable */ * dt)
x60c_ += dt;
else
x60c_ = 0.f;
x614_ = GetTranslation();
if (x608_ > 0.f)
x608_ -= dt;
else
x608_ = 0.f;
}
}
if (x400_25_)
{
CPlayer* pl = mgr.Player();
float radius;
if (pl->GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed && !x742_30_)
radius = x590_colSphere.GetSphere().radius;
else
radius = x708_;
zeus::CAABox aabox{GetTranslation() - radius, GetTranslation() + radius};
auto plBox = pl->GetTouchBounds();
if (plBox && plBox->intersects(aabox))
{
if (!x742_30_)
{
x742_30_ = true;
x742_27_ = false;
}
if (x420_curDamageTime <= 0.f)
{
mgr.ApplyDamage(GetUniqueId(), pl->GetUniqueId(), GetUniqueId(), GetContactDamage(),
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {}), {});
x420_curDamageTime = x424_damageWaitTime;
}
}
}
CWallWalker::Think(dt, mgr);
if (x5d6_27_)
return;
if (x450_bodyController->IsFrozen())
return;
x3b4_speed = x604_;
if (x5d6_24_)
AlignToFloor(mgr, x590_colSphere.GetSphere().radius, GetTranslation() + 2.f * dt * x138_velocity, dt);
x742_27_ = false;
}
void CParasite::DestroyActorManager(CStateManager& mgr)
{
//x620_->Destroy(mgr);
}
void CParasite::UpdateJumpVelocity()
{
x150_momentum.x = 0;
x150_momentum.y = 0;
x150_momentum.z = -GetWeight();
zeus::CVector3f vec;
if (!x742_30_)
{
vec = skAttackVelocity * GetTransform().frontVector();
vec.z = 0.5f * skRetreatVelocity;
}
else
{
vec = skRetreatVelocity * GetTransform().frontVector();
vec.z = 0.5f * skAttackVelocity;
}
float f30 = x150_momentum.z / xe8_mass;
float f31 = x600_ - GetTranslation().z;
zeus::CVector3f vec2;
vec2.x = x5f8_ - GetTranslation().x;
vec2.y = x5fc_ * GetTranslation().y;
vec2.z = 0.f;
float f29 = vec2.magnitude();
if (f29 > FLT_EPSILON)
{
vec2 *= zeus::CVector3f{1.f / f29};
float f28 = vec2.dot(vec);
if (f28 > FLT_EPSILON)
{
float f27 = 0.f;
bool isNeg = f31 < 0.f;
float out1, out2;
if (CSteeringBehaviors::SolveQuadratic(f30, vec.z, -f31, vec2.y, out1, out2))
f27 = isNeg ? out1 : out2;
if (!isNeg)
f27 = f27 * f29 / f28;
if (f27 < 10.f)
{
vec = f29 / f27 * vec2;
vec.z = (0.5f * f30 * f27 + f31 / f27);
}
}
}
SetVelocityWR(vec);
}
void CParasite::AlignToFloor(CStateManager&, float, const zeus::CVector3f&, float)
{
}
} // namespace urde::MP1

View File

@ -2,7 +2,7 @@
#define __URDE_MP1_CPARASITE_HPP__
#include "World/CWallWalker.hpp"
#include "Collision/CCollisionActorManager.hpp"
namespace urde
{
class CModelData;
@ -10,41 +10,109 @@ class CModelData;
namespace urde::MP1
{
struct CParasiteInfo
{
u32 x0_ = 0;
union
{
struct
{
bool x4_24_ : 1; bool x4_26_ : 1;
};
u32 x4_dummy = 0;
};
float x8_ = 0.f;
float xc_ = 0.f;
float x10_ = 0.f;
float x14_ = 0.f;
union
{
struct
{
bool x18_24_ : 1;
};
u32 x18_dummy = 0;
};
};
class CParasite : public CWallWalker
{
class CRepulsor
{
};
static const float flt_805A8FB0;
static const float skAttackVelocity;
static short word_805A8FC0;
static const float flt_805A8FB8;
static const float skRetreatVelocity;
std::vector<CRepulsor> x5d8_doorRepulsors;
s32 x5e8_ = -1;
float x5ec_ = 0.f;
float x5f0_ = 0.f;
float x5f4_ = 0.f;
float x5f8_ = 0.f;
float x5fc_ = 0.f;
float x600_ = 0.f;
float x604_ = 1.f;
float x608_ = 0.f;
float x60c_ = 0.f;
zeus::CVector3f x614_;
std::unique_ptr<CCollisionActorManager> x620_ = 0;
u32 x624_ = 0;
float x628_ = 0.f;
float x62c_ = 0.f;
float x630_ = 0.f;
float x634_ = 0.f;
float x638_ = 0.f;
float x640_ = 0.f;
float x644_ = 0.f;
float x648_ = 0.f;
CDamageVulnerability x64c_;
CDamageInfo x6b4_;
float x6d0_;
float x6d4_;
float x6dc_;
float x6e0_;
float x6e4_;
float x6e8_;
float x6ec_;
float x6f0_;
float x6f4_;
float x6f8_;
float x6fc_;
float x700_;
float x704_;
float x708_;
float x710_;
float x714_;
float x718_ = 0.f;
float x71c_ = 0.f;
float x720_ = 0.f;
float x724_ = 0.f;
float x728_ = 0.f;
float x72c_ = 0.f;
float x730_ = 0.f;
float x734_ = 0.f;
float x738_ = 0.f;
s16 x73c_;
s16 x73e_;
s16 x740_;
union
{
struct
{
bool x742_24_ : 1;
bool x742_25_ : 1;
bool x742_26_ : 1;
bool x742_27_ : 1;
bool x742_28_ : 1;
bool x742_29_ : 1;
bool x742_30_ : 1;
bool x742_31_ : 1;
bool x743_24_ : 1;
bool x743_25_ : 1;
bool x743_26_ : 1;
bool x743_27_ : 1;
};
u16 _dummy = 0;
};
public:
DEFINE_PATTERNED(Parasite)
CParasite(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo& info, const zeus::CTransform& xf,
CModelData&& mData, const CPatternedInfo&, u32, float, float, float, float, float, float, float, float, float,
float, float, float, float, float, float, float, float, float, bool, u32, const CDamageVulnerability&, const CParasiteInfo&, u16, u16,
u16, u32, u32, float, const CActorParameters&);
CParasite(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo& info,
const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo&, EBodyType, float, float, float,
float, float, float, float, float, float, float, float, float, float, float, float, float, float, float,
bool, u32, const CDamageVulnerability&, const CDamageInfo&, u16, u16, u16, u32, u32, float,
const CActorParameters&);
void Accept(IVisitor&);
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
void PreThink(float, CStateManager&);
void Think(float dt, CStateManager& mgr);
void DestroyActorManager(CStateManager& mgr);
void UpdateJumpVelocity();
void UpdateCollisionActors(CStateManager&) {}
CDamageInfo GetContactDamage() const
{
if (x5d0_ == 1 && x743_24_)
return x6b4_;
return CPatterned::GetContactDamage();
}
void AlignToFloor(CStateManager&, float, const zeus::CVector3f&, float);
};
}
#endif // __URDE_MP1_CPARASITE_HPP__

View File

@ -8,8 +8,9 @@ namespace MP1
CSeedling::CSeedling(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf,
CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& actParms,
CAssetId, CAssetId, const CDamageInfo&, const CDamageInfo&, float, float, float, float)
: CWallWalker(ECharacter::Seedling, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo, EMovementType::Ground, EColliderType::Zero, EBodyType::WallWalker, actParms, 0, 4)
CAssetId, CAssetId, const CDamageInfo&, const CDamageInfo&, float f1, float f2, float f3, float f4)
: CWallWalker(ECharacter::Seedling, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo,
EMovementType::Ground, EColliderType::Zero, EBodyType::WallWalker, actParms, f1, f2, 0, f3, 4, f4, false)
{
}

View File

@ -15,9 +15,11 @@ CBeamProjectile::CBeamProjectile(const TToken<CWeaponDescription>& wDesc, std::s
, x2f0_(1.f / x2ec_)
, x2f4_(f1)
, x300_(b1 == false ? x2ec_ : 0.f)
, x308_(f2)
, x464_24_(b1)
, x464_25_(false)
{
}
std::experimental::optional<zeus::CAABox> CBeamProjectile::GetTouchBounds() const

View File

@ -320,8 +320,8 @@ void CPatterned::Think(float dt, CStateManager& mgr)
//x460_.sub80233b58(thinkDt, mgr, *this);
x4e4_ = GetTranslation() + PredictMotion(thinkDt).x0_translation;
x328_26_ = false;
if (x420_ > 0.f)
x420_ -= dt;
if (x420_curDamageTime > 0.f)
x420_curDamageTime -= dt;
if (x401_28_ && x3f4_ > dt)
x3f4_ -= dt;
@ -527,7 +527,7 @@ void CPatterned::ThinkAboutMove(float dt)
if (!x401_26_ && doMove)
{
const CBodyState* state = x450_bodyController->GetBodyStateInfo().GetCurrentState();
if (state->ApplyAnimationDeltas() && !zeus::close_enough(x2e0_ - GetTranslation(), {}))
if (state->ApplyAnimationDeltas() && !zeus::close_enough(x2e0_destPos - GetTranslation(), {}))
MoveToOR((x64_modelData->GetScale() * x434_posDelta) * x55c_, dt);
}

View File

@ -107,7 +107,7 @@ public:
protected:
u32 x2d8_ = -1;
TUniqueId x2dc_ = kInvalidUniqueId;
zeus::CVector3f x2e0_;
zeus::CVector3f x2e0_destPos;
zeus::CVector3f x2ec_;
float x2f8_ = 0.f;
float x2fc_minAttackRange;
@ -205,7 +205,7 @@ protected:
};
CDamageInfo x404_contactDamage;
float x420_ = 0.f;
float x420_curDamageTime = 0.f;
float x424_damageWaitTime;
float x428_ = -1.f;
zeus::CColor x42c_ = zeus::CColor::skBlack;
@ -242,6 +242,7 @@ public:
void Accept(IVisitor&);
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
void PreThink(float, CStateManager& mgr) { CEntity::Think(x500_, mgr); }
void Think(float, CStateManager&);
void PreRender(CStateManager&, const zeus::CFrustum&);
@ -270,7 +271,7 @@ public:
virtual void Shock(float, float) {}
virtual void ThinkAboutMove(float);
virtual void GetSearchPath() {}
virtual CDamageInfo GetContactDamage() { return x404_contactDamage; }
virtual CDamageInfo GetContactDamage() const { return x404_contactDamage; }
virtual u8 GetModelAlphau8(const CStateManager&) const { return u8(x42c_.a * 255);}
virtual bool IsOnGround() const { return x328_27_onGround; }
virtual float GetGravityConstant() const { return 24.525002f; }
@ -286,6 +287,7 @@ public:
void SetupPlayerCollision(bool);
void SetDestPos(const zeus::CVector3f& pos) { x2e0_destPos = pos; }
void sub8007a68c(float, CStateManager&) {}
float sub80078a88();
void sub8007a5b8(float) {}

View File

@ -62,6 +62,9 @@ public:
CAnimationParameters& GetAnimationParameters() { return xec_animParams; }
const CAnimationParameters& GetAnimationParameters() const { return xec_animParams; }
float GetHalfExtent() const { return xc4_halfExtent; }
float GetHeight() const { return xc8_height; }
};
}

View File

@ -247,17 +247,14 @@ void CPhysicsActor::ComputeDerivedQuantities()
bool CPhysicsActor::WillMove(const CStateManager&)
{
if (!zeus::close_enough(zeus::CVector3f::skZero, x138_velocity) ||
!zeus::close_enough(zeus::CVector3f::skZero, x168_impulse) ||
!zeus::close_enough(zeus::CVector3f::skZero, x174_torque) ||
!zeus::close_enough(zeus::CVector3f::skZero, x18c_moveImpulse) ||
!zeus::close_enough(zeus::CVector3f::skZero, x144_angularVelocity) ||
!zeus::close_enough(zeus::CVector3f::skZero, x180_angularImpulse) ||
!zeus::close_enough(zeus::CVector3f::skZero, x198_moveAngularImpulse) ||
!zeus::close_enough(zeus::CVector3f::skZero, GetTotalForcesWR()))
return true;
return false;
return !zeus::close_enough(zeus::CVector3f::skZero, x138_velocity) ||
!zeus::close_enough(zeus::CVector3f::skZero, x168_impulse) ||
!zeus::close_enough(zeus::CVector3f::skZero, x174_torque) ||
!zeus::close_enough(zeus::CVector3f::skZero, x18c_moveImpulse) ||
!zeus::close_enough(zeus::CVector3f::skZero, x144_angularVelocity) ||
!zeus::close_enough(zeus::CVector3f::skZero, x180_angularImpulse) ||
!zeus::close_enough(zeus::CVector3f::skZero, x198_moveAngularImpulse) ||
!zeus::close_enough(zeus::CVector3f::skZero, GetTotalForcesWR());
}
void CPhysicsActor::SetPhysicsState(const CPhysicsState& state)

View File

@ -28,6 +28,7 @@ public:
TUniqueId FollowWaypoint(CStateManager& mgr) const;
TUniqueId NextWaypoint(CStateManager& mgr) const;
float GetSpeed() const { return xe8_speed; }
float GetF0() const { return xf0_; }
};
}

View File

@ -1,11 +1,115 @@
#include "CWallWalker.hpp"
#include "CPatternedInfo.hpp"
#include "CStateManager.hpp"
#include "TCastTo.hpp"
#include "CScriptWaypoint.hpp"
namespace urde
{
CWallWalker::CWallWalker(ECharacter chr, TUniqueId uid, std::string_view name, EFlavorType flavType,
const CEntityInfo& eInfo, const zeus::CTransform& xf,
CModelData&& mData, const CPatternedInfo& pInfo, EMovementType mType,
EColliderType colType, EBodyType bType, const CActorParameters& aParms, s32 w1, u32 w2)
: CPatterned(chr, uid, name, flavType, eInfo, xf, std::move(mData), pInfo, mType, colType, bType, aParms, w1)
{}
EColliderType colType, EBodyType bType, const CActorParameters& aParms, float f1, float f2,
s32 w1, float f3, u32 w2, float f4, bool b1)
: CPatterned(chr, uid, name, flavType, eInfo, xf, std::move(mData), pInfo, mType, colType, bType, aParms, w1)
, x590_colSphere(zeus::CSphere(zeus::CVector3f::skZero, pInfo.GetHalfExtent()), x68_material)
, x5b0_(f1)
, x5b4_(f2)
, x5c0_(f3)
, x5c4_(f4)
, x5cc_bendingHackAnim(GetModelData()->GetAnimationData()->GetCharacterInfo().GetAnimationIndex("BendingAnimationHack"sv))
, x5d0_(w2)
, x5d6_24_(false)
, x5d6_25_(false)
, x5d6_26_(false)
, x5d6_27_(b1)
, x5d6_28_addBendingWeight(true)
, x5d6_29_applyBendingHack(false)
{
}
void CWallWalker::PreThink(float dt, CStateManager& mgr)
{
CPatterned::PreThink(dt, mgr);
if (!GetActive() || x5d6_26_ || x5bc_ > 0.f || x5d6_27_ || x450_bodyController->IsFrozen() || !x5d6_24_)
return;
zeus::CQuaternion quat(GetTransform().buildMatrix3f());
AddMotionState(PredictMotion(dt));
zeus::CQuaternion quat2(GetTransform().buildMatrix3f());
ClearForcesAndTorques();
if (x5d6_25_)
{
zeus::CPlane plane = x568_.GetPlane();
const float futureDt = (10.f * dt);
SetTranslation(GetTranslation() * (1.f - futureDt) +
(((GetTranslation() - ((plane.vec.dot(GetTranslation())) - plane.d) -
x590_colSphere.GetSphere().radius - 0.1f) * plane.vec) * futureDt));
}
else
MoveCollisionPrimitive(zeus::CVector3f::skZero);
}
void CWallWalker::Think(float dt, CStateManager& mgr)
{
if (!x450_bodyController->GetActive())
x450_bodyController->Activate(mgr);
CPatterned::Think(dt, mgr);
if (x5cc_bendingHackAnim == -1)
return;
if (x5d6_28_addBendingWeight)
{
if (x5c8_bendingHackWeight < 1.f)
{
x5c8_bendingHackWeight += (dt * x138_velocity.magnitude()) / 0.6f;
if (x5c8_bendingHackWeight >= 1.f)
x5c8_bendingHackWeight = 1.f;
}
}
else if (x5c8_bendingHackWeight > 0.f)
{
x5c8_bendingHackWeight -= (dt * x138_velocity.magnitude()) / 1.5f;
if (x5c8_bendingHackWeight < 0.f)
x5c8_bendingHackWeight = 0.f;
}
if (x5c8_bendingHackWeight <= 0.f && !x5d6_29_applyBendingHack)
return;
if (x5c8_bendingHackWeight > 0.0001f)
{
ModelData()->AnimationData()->AddAdditiveAnimation(x5cc_bendingHackAnim, x5c8_bendingHackWeight, true, false);
x5d6_29_applyBendingHack = true;
}
else
{
ModelData()->AnimationData()->DelAdditiveAnimation(x5cc_bendingHackAnim);
x5d6_29_applyBendingHack = false;
}
}
void CWallWalker::UpdateWPDestination(CStateManager& mgr)
{
if (TCastToPtr<CScriptWaypoint> wp = mgr.ObjectById(x2dc_))
{
zeus::CVector3f wpPos = wp->GetTranslation();
if ((wpPos - GetTranslation()).magSquared() < x5c0_ * x5c0_)
{
x2dc_ = wp->NextWaypoint(mgr);
if (std::fabs(wp->GetF0()) > 0.00001f)
{
x5bc_ = wp->GetF0();
if (x5d0_ == 0)
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed);
mgr.SendScriptMsg(wp, GetUniqueId(), EScriptObjectMessage::Arrived);
}
}
SetDestPos(wpPos);
}
}
}

View File

@ -2,15 +2,43 @@
#define __URDE_CWALLWALKER_HPP__
#include "CPatterned.hpp"
#include "Collision/CCollisionSurface.hpp"
#include "Collision/CCollidableSphere.hpp"
namespace urde
{
class CWallWalker : public CPatterned
{
protected:
CCollisionSurface x568_ = CCollisionSurface(zeus::CVector3f(),
zeus::CVector3f::skForward,
zeus::CVector3f::skRight, -1);
CCollidableSphere x590_colSphere;
float x5b0_;
float x5b4_;
float x5b8_ = 0.f;
float x5bc_ = 0.f;
float x5c0_;
float x5c4_;
float x5c8_bendingHackWeight = 0.f;
s32 x5cc_bendingHackAnim;
u32 x5d0_;
s16 x5d4_ = 0;
bool x5d6_24_ : 1;
bool x5d6_25_ : 1;
bool x5d6_26_ : 1;
bool x5d6_27_ : 1;
bool x5d6_28_addBendingWeight : 1;
bool x5d6_29_applyBendingHack : 1;
public:
CWallWalker(ECharacter, TUniqueId, std::string_view, EFlavorType, const CEntityInfo&, const zeus::CTransform&,
CModelData&&, const CPatternedInfo&, EMovementType, EColliderType, EBodyType,
const CActorParameters&, s32, u32);
const CActorParameters&, float, float, s32, float, u32, float, bool);
void PreThink(float, CStateManager&);
void Think(float, CStateManager&);
const CCollisionPrimitive* GetCollisionPrimitive() const { return &x590_colSphere; }
void UpdateWPDestination(CStateManager&);
};
}
#endif // __URDE_CWALLWALKER_HPP__

View File

@ -1652,10 +1652,10 @@ CEntity* ScriptLoader::LoadParasite(CStateManager& mgr, CInputStream& in, int pr
const CAnimationParameters& animParms = pInfo.GetAnimationParameters();
CModelData mData(
CAnimRes(animParms.GetACSFile(), animParms.GetCharacter(), scale, animParms.GetInitialAnimation(), true));
return new MP1::CParasite(mgr.AllocateUniqueId(), name, flavor, info, xf, std::move(mData), pInfo, 6, f1, f2, f3,
f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, 0.f, b1, 0,
CDamageVulnerability::NormalVulnerabilty(), MP1::CParasiteInfo(), -1, -1, -1, -1, -1, 0.f,
aParms);
return new MP1::CParasite(mgr.AllocateUniqueId(), name, flavor, info, xf, std::move(mData), pInfo,
EBodyType::WallWalker, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, 0.f, b1, 0, CDamageVulnerability::NormalVulnerabilty(), CDamageInfo(),
-1, -1, -1, -1, -1, 0.f, aParms);
}
CEntity* ScriptLoader::LoadPlayerHint(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)
@ -2584,9 +2584,11 @@ CEntity* ScriptLoader::LoadGeemer(CStateManager& mgr, CInputStream& in, int prop
CModelData mData(CAnimRes(pInfo.GetAnimationParameters().GetACSFile(), pInfo.GetAnimationParameters().GetCharacter(),
actHead.x40_scale, pInfo.GetAnimationParameters().GetInitialAnimation(), true));
return new MP1::CParasite(mgr.AllocateUniqueId(), actHead.x0_name, CPatterned::EFlavorType::Zero, info, actHead.x10_transform,
std::move(mData), pInfo, 6, 0.f, f1, f2, f3, f4, 0.2f, 0.4f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f, f7, 0.f, 0.f,
f5, f6, false, 2, CDamageVulnerability::NormalVulnerabilty(), MP1::CParasiteInfo(), sId1, sId2, sId3, -1, -1, 0.f, actParms);
return new MP1::CParasite(mgr.AllocateUniqueId(), actHead.x0_name, CPatterned::EFlavorType::Zero, info,
actHead.x10_transform, std::move(mData), pInfo, EBodyType::WallWalker, 0.f, f1, f2, f3, f4, 0.2f, 0.4f, 0.f,
0.f, 0.f, 0.f, 0.f, 1.f, f7, 0.f, 0.f, f5, f6, false, 2,
CDamageVulnerability::NormalVulnerabilty(), CDamageInfo(), sId1, sId2, sId3, -1,
-1, 0.f, actParms);
}
CEntity* ScriptLoader::LoadSpindleCamera(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)