mirror of https://github.com/AxioDL/metaforce.git
More CFlaahgra imps, initial CTryclops imps
This commit is contained in:
parent
91fe17dcbb
commit
328749d1ba
|
@ -188,25 +188,22 @@ bool CAnimData::IsAdditiveAnimation(s32 idx) const {
|
|||
|
||||
bool CAnimData::IsAdditiveAnimationAdded(s32 idx) const {
|
||||
s32 animIdx = xc_charInfo.GetAnimationIndex(idx);
|
||||
auto search =
|
||||
std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(),
|
||||
[animIdx](const auto& pair) { return pair.first == animIdx; });
|
||||
auto search = std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(),
|
||||
[animIdx](const auto& pair) { return pair.first == animIdx; });
|
||||
return search != x434_additiveAnims.cend();
|
||||
}
|
||||
|
||||
const std::shared_ptr<CAnimTreeNode>& CAnimData::GetAdditiveAnimationTree(s32 idx) const {
|
||||
s32 animIdx = xc_charInfo.GetAnimationIndex(idx);
|
||||
auto search =
|
||||
std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(),
|
||||
[animIdx](const auto& pair) { return pair.first == animIdx; });
|
||||
auto search = std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(),
|
||||
[animIdx](const auto& pair) { return pair.first == animIdx; });
|
||||
return search->second.GetAnim();
|
||||
}
|
||||
|
||||
bool CAnimData::IsAdditiveAnimationActive(s32 idx) const {
|
||||
s32 animIdx = xc_charInfo.GetAnimationIndex(idx);
|
||||
auto search =
|
||||
std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(),
|
||||
[animIdx](const auto& pair) { return pair.first == animIdx; });
|
||||
auto search = std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(),
|
||||
[animIdx](const auto& pair) { return pair.first == animIdx; });
|
||||
if (search == x434_additiveAnims.cend())
|
||||
return false;
|
||||
return search->second.IsActive();
|
||||
|
@ -214,11 +211,9 @@ bool CAnimData::IsAdditiveAnimationActive(s32 idx) const {
|
|||
|
||||
void CAnimData::DelAdditiveAnimation(s32 idx) {
|
||||
s32 animIdx = xc_charInfo.GetAnimationIndex(idx);
|
||||
auto search =
|
||||
std::find_if(x434_additiveAnims.begin(), x434_additiveAnims.end(),
|
||||
[animIdx](const auto& pair) { return pair.first == animIdx; });
|
||||
if (search != x434_additiveAnims.cend() &&
|
||||
search->second.GetPhase() != EAdditivePlaybackPhase::FadingOut &&
|
||||
auto search = std::find_if(x434_additiveAnims.begin(), x434_additiveAnims.end(),
|
||||
[animIdx](const auto& pair) { return pair.first == animIdx; });
|
||||
if (search != x434_additiveAnims.cend() && search->second.GetPhase() != EAdditivePlaybackPhase::FadingOut &&
|
||||
search->second.GetPhase() != EAdditivePlaybackPhase::FadedOut) {
|
||||
search->second.FadeOut();
|
||||
}
|
||||
|
@ -226,26 +221,25 @@ void CAnimData::DelAdditiveAnimation(s32 idx) {
|
|||
|
||||
void CAnimData::AddAdditiveAnimation(s32 idx, float weight, bool active, bool fadeOut) {
|
||||
s32 animIdx = xc_charInfo.GetAnimationIndex(idx);
|
||||
auto search =
|
||||
std::find_if(x434_additiveAnims.begin(), x434_additiveAnims.end(),
|
||||
[animIdx](const auto& pair) { return pair.first == animIdx; });
|
||||
auto search = std::find_if(x434_additiveAnims.begin(), x434_additiveAnims.end(),
|
||||
[animIdx](const auto& pair) { return pair.first == animIdx; });
|
||||
if (search != x434_additiveAnims.cend()) {
|
||||
search->second.SetActive(active);
|
||||
search->second.SetWeight(weight);
|
||||
search->second.SetNeedsFadeOut(!search->second.IsActive() && fadeOut);
|
||||
} else {
|
||||
std::shared_ptr<CAnimTreeNode> node =
|
||||
GetAnimationManager()->GetAnimationTree(animIdx, CMetaAnimTreeBuildOrders::NoSpecialOrders());
|
||||
GetAnimationManager()->GetAnimationTree(animIdx, CMetaAnimTreeBuildOrders::NoSpecialOrders());
|
||||
const CAdditiveAnimationInfo& info = x0_charFactory->FindAdditiveInfo(animIdx);
|
||||
x434_additiveAnims.emplace_back(std::make_pair(animIdx, CAdditiveAnimPlayback(node, weight, active, info, fadeOut)));
|
||||
x434_additiveAnims.emplace_back(
|
||||
std::make_pair(animIdx, CAdditiveAnimPlayback(node, weight, active, info, fadeOut)));
|
||||
}
|
||||
}
|
||||
|
||||
float CAnimData::GetAdditiveAnimationWeight(s32 idx) const {
|
||||
s32 animIdx = xc_charInfo.GetAnimationIndex(idx);
|
||||
auto search =
|
||||
std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(),
|
||||
[animIdx](const auto& pair) { return pair.first == animIdx; });
|
||||
auto search = std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(),
|
||||
[animIdx](const auto& pair) { return pair.first == animIdx; });
|
||||
if (search != x434_additiveAnims.cend())
|
||||
return search->second.GetTargetWeight();
|
||||
return 0.f;
|
||||
|
@ -541,15 +535,13 @@ void CAnimData::RecalcPoseBuilder(const CCharAnimTime* time) {
|
|||
void CAnimData::RenderAuxiliary(const zeus::CFrustum& frustum) const { x120_particleDB.AddToRendererClipped(frustum); }
|
||||
|
||||
void CAnimData::Render(CSkinnedModel& model, const CModelFlags& drawFlags,
|
||||
const std::optional<CVertexMorphEffect>& morphEffect,
|
||||
const float* morphMagnitudes) {
|
||||
const std::optional<CVertexMorphEffect>& morphEffect, const float* morphMagnitudes) {
|
||||
SetupRender(model, drawFlags, morphEffect, morphMagnitudes);
|
||||
DrawSkinnedModel(model, drawFlags);
|
||||
}
|
||||
|
||||
void CAnimData::SetupRender(CSkinnedModel& model, const CModelFlags& drawFlags,
|
||||
const std::optional<CVertexMorphEffect>& morphEffect,
|
||||
const float* morphMagnitudes) {
|
||||
const std::optional<CVertexMorphEffect>& morphEffect, const float* morphMagnitudes) {
|
||||
if (!x220_30_poseBuilt) {
|
||||
x2fc_poseBuilder.BuildNoScale(x224_pose);
|
||||
x220_30_poseBuilt = true;
|
||||
|
@ -798,8 +790,7 @@ void CAnimData::SetInfraModel(const TLockedToken<CModel>& model, const TLockedTo
|
|||
}
|
||||
|
||||
void CAnimData::PoseSkinnedModel(CSkinnedModel& model, const CPoseAsTransforms& pose, const CModelFlags& drawFlags,
|
||||
const std::optional<CVertexMorphEffect>& morphEffect,
|
||||
const float* morphMagnitudes) {
|
||||
const std::optional<CVertexMorphEffect>& morphEffect, const float* morphMagnitudes) {
|
||||
model.Calculate(pose, drawFlags, morphEffect, morphMagnitudes);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,9 +2,12 @@
|
|||
#include "CAnimSourceReader.hpp"
|
||||
|
||||
namespace urde {
|
||||
|
||||
CInt32POINode::CInt32POINode()
|
||||
: CPOINode("root", EPOIType::EmptyInt32, CCharAnimTime(), -1, false, 1.f, -1, 0), x38_val(0), x3c_locatorName("root") {}
|
||||
: CInt32POINode(""sv, EPOIType::EmptyInt32, CCharAnimTime(), -1, false, 1.f, -1, 0, 0, "root"sv) {}
|
||||
|
||||
CInt32POINode::CInt32POINode(std::string_view name, EPOIType type, const CCharAnimTime& time, s32 index, bool unique, float weight, s32 charIndex,
|
||||
s32 flags, s32 val, std::string_view locator)
|
||||
: CPOINode(name, type, time, index, unique, weight, charIndex, flags), x38_val(val), x3c_locatorName(locator) {}
|
||||
|
||||
CInt32POINode::CInt32POINode(CInputStream& in)
|
||||
: CPOINode(in), x38_val(in.readUint32Big()), x3c_locatorName(in.readString()) {}
|
||||
|
|
|
@ -11,6 +11,7 @@ class CInt32POINode : public CPOINode {
|
|||
|
||||
public:
|
||||
CInt32POINode();
|
||||
CInt32POINode(std::string_view, EPOIType, const CCharAnimTime&, s32, bool, float, s32, s32, s32, std::string_view);
|
||||
CInt32POINode(CInputStream& in);
|
||||
s32 GetValue() const { return x38_val; }
|
||||
std::string_view GetLocatorName() const { return x3c_locatorName; }
|
||||
|
|
|
@ -64,7 +64,7 @@ enum class EHurledState {
|
|||
Seven
|
||||
};
|
||||
|
||||
enum class EFallState { Invalid = -1, Zero };
|
||||
enum class EFallState { Invalid = -1, Zero, One };
|
||||
|
||||
enum class EReactionType { Invalid = -1, Zero, One, Two, Three };
|
||||
|
||||
|
@ -77,8 +77,18 @@ enum class EJumpState { Invalid = -1, IntoJump, AmbushJump, Loop, OutOfJump, Wal
|
|||
enum class EStepDirection { Invalid = -1, Forward = 0, Backward = 1, Left = 2, Right = 3, Up = 4, Down = 5 };
|
||||
|
||||
enum class EStepType { Normal = 0, Dodge = 1, BreakDodge = 2, RollDodge = 3 };
|
||||
|
||||
enum class ESeverity { Invalid = -1, Zero = 0, One = 1, Two = 2, Three, Four, Seven = 7, Eight = 8 };
|
||||
enum class ESeverity {
|
||||
Invalid = -1,
|
||||
Zero = 0,
|
||||
One = 1,
|
||||
Two = 2,
|
||||
Three = 3,
|
||||
Four = 4,
|
||||
Five = 5,
|
||||
Six = 6,
|
||||
Seven = 7,
|
||||
Eight = 8
|
||||
};
|
||||
|
||||
enum class EGetupType { Invalid = -1, Zero = 0, One = 1, Two = 2 };
|
||||
|
||||
|
|
|
@ -197,7 +197,7 @@ public:
|
|||
|
||||
void DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt);
|
||||
|
||||
float GetGravityConstant() const { return 10.f * 24.525f; }
|
||||
float GetGravityConstant() const { return 10.f * CPhysicsActor::GravityConstant(); }
|
||||
|
||||
void SetPathFindMode(EPathFindMode mode) { x8b4_pathFindMode = mode; }
|
||||
|
||||
|
|
|
@ -982,6 +982,6 @@ void CBeetle::Shock(CStateManager& mgr, float duration, float damage) {
|
|||
|
||||
CPathFindSearch* CBeetle::GetSearchPath() { return &x5fc_pathFindSearch; }
|
||||
|
||||
float CBeetle::GetGravityConstant() const { return 4.f * 24.525f; }
|
||||
float CBeetle::GetGravityConstant() const { return 4.f * CPhysicsActor::GravityConstant(); }
|
||||
|
||||
} // namespace urde::MP1
|
||||
|
|
|
@ -76,7 +76,21 @@ CFlaahgra::CFlaahgra(TUniqueId uid, std::string_view name, const CEntityInfo& in
|
|||
, x820_(xf.origin)
|
||||
, x8a0_(xf.frontVector())
|
||||
, x8ac_(animRes) {
|
||||
x8e4_24_loaded = false;
|
||||
x8e4_25_loading = false;
|
||||
x8e4_26_ = false;
|
||||
x8e4_27_ = false;
|
||||
x8e4_28_ = false;
|
||||
x8e4_29_getup = false;
|
||||
x8e4_30_ = false;
|
||||
x8e4_31_ = false;
|
||||
x8e5_24_ = false;
|
||||
x8e5_25_ = false;
|
||||
x8e5_26_ = false;
|
||||
x8e5_27_ = false;
|
||||
x8e5_28_ = false;
|
||||
x8e5_29_ = true;
|
||||
x8e5_30_ = false;
|
||||
x6dc_.Token().Lock();
|
||||
x704_.Token().Lock();
|
||||
x7dc_.SetDamage(0.5f * x7dc_.GetDamage());
|
||||
|
@ -115,7 +129,7 @@ void CFlaahgra::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateM
|
|||
}
|
||||
case EScriptObjectMessage::Activate: {
|
||||
GatherAssets(mgr);
|
||||
if (x8e5_25_)
|
||||
if (x8e5_27_)
|
||||
break;
|
||||
|
||||
SetupCollisionManagers(mgr);
|
||||
|
@ -150,10 +164,10 @@ void CFlaahgra::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateM
|
|||
if (x7a8_ == 4)
|
||||
contactDamage = x7dc_;
|
||||
|
||||
if (sub801ae670())
|
||||
if (!sub801ae670())
|
||||
contactDamage.SetDamage(0.5f * contactDamage.GetDamage());
|
||||
|
||||
if (x788_ == 2)
|
||||
if (x788_ >= 2)
|
||||
contactDamage.SetDamage(1.33f * contactDamage.GetDamage());
|
||||
|
||||
mgr.ApplyDamage(GetUniqueId(), mgr.GetPlayer().GetUniqueId(), GetUniqueId(), contactDamage,
|
||||
|
@ -266,6 +280,7 @@ void CFlaahgra::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, E
|
|||
return;
|
||||
}
|
||||
case EUserEventType::BeginAction: {
|
||||
printf("BeginAction\n");
|
||||
x8e4_26_ = true;
|
||||
x7c4_ = GetEndActionTime();
|
||||
break;
|
||||
|
@ -504,21 +519,26 @@ void CFlaahgra::sub801ae980(CStateManager& mgr) {
|
|||
HealthInfo(mgr)->SetHP(HealthInfo(mgr)->GetHP() - x56c_.x8_);
|
||||
x7d4_ = x56c_.xc_;
|
||||
x8e4_29_getup = true;
|
||||
x7d8_ = 0.f;
|
||||
x430_damageColor = skUnkColor;
|
||||
++x788_;
|
||||
}
|
||||
|
||||
void CFlaahgra::sub801ade80() {
|
||||
x894_ = (x7ac_ ? -GetTransform().basis[0] : GetTransform().basis[0]);
|
||||
x894_ = (x7ac_ == 0 ? -GetTransform().basis[0] : GetTransform().basis[0]);
|
||||
|
||||
const rstl::reserved_vector<zeus::CVector3f, 4>& vec = (x7ac_ ? x82c_ : x860_);
|
||||
const rstl::reserved_vector<zeus::CVector3f, 4>& vec = (x7ac_ == 0 ? x860_ : x82c_);
|
||||
|
||||
float curDist = FLT_MIN;
|
||||
for (const zeus::CVector3f& v : vec) {
|
||||
if (v.magSquared() < 0.f)
|
||||
continue;
|
||||
|
||||
if (GetTransform().basis[1].dot(v) > FLT_MIN)
|
||||
float dist = GetTransform().basis[1].dot(v);
|
||||
if (dist > curDist) {
|
||||
curDist = dist;
|
||||
x894_ = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -539,8 +559,7 @@ bool CFlaahgra::ShouldAttack(CStateManager& mgr, float) {
|
|||
(x7cc_ > 0.f || player.GetVelocity().magSquared() < 25.f))
|
||||
return false;
|
||||
|
||||
|
||||
return zeus::CVector2f::getAngleDiff(GetTransform().basis[1].toVec2f(), diff) > zeus::degToRad(45.f);
|
||||
return zeus::CVector2f::getAngleDiff(GetTransform().basis[1].toVec2f(), diff) < zeus::degToRad(45.f);
|
||||
}
|
||||
|
||||
void CFlaahgra::UpdateHeadDamageVulnerability(CStateManager& mgr, bool b) {
|
||||
|
@ -567,6 +586,7 @@ void CFlaahgra::FadeOut(CStateManager& mgr, EStateMsg msg, float) {
|
|||
x7a4_sphereCollision->SetActive(mgr, true);
|
||||
x79c_leftArmCollision->SetActive(mgr, true);
|
||||
x7a0_rightArmCollision->SetActive(mgr, true);
|
||||
x784_ = x780_;
|
||||
x81c_ = GetModelData()->GetScale().z();
|
||||
UpdateScale(1.f, x81c_, x56c_.x4_);
|
||||
x8e4_26_ = false;
|
||||
|
@ -601,7 +621,7 @@ void CFlaahgra::UpdateSmallScaleReGrowth(float dt) {
|
|||
if (!x8e4_29_getup || x7d8_ > 6.f)
|
||||
return;
|
||||
|
||||
x430_damageColor = zeus::CColor::lerp(skUnkColor, zeus::skBlack, (M_PIF * std::cos(x7d8_)));
|
||||
x430_damageColor = zeus::CColor::lerp(skUnkColor, zeus::skBlack, std::round(std::fabs(M_PIF * std::cos(x7d8_))));
|
||||
TakeDamage({}, 0.f);
|
||||
x7d8_ += dt;
|
||||
}
|
||||
|
@ -718,7 +738,7 @@ void CFlaahgra::GetUp(CStateManager& mgr, EStateMsg msg, float) {
|
|||
SetCollisionActorBounds(mgr, x79c_leftArmCollision, skUnkVec1);
|
||||
SetCollisionActorBounds(mgr, x7a0_rightArmCollision, skUnkVec1);
|
||||
} else {
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCGetupCmd(pas::EGetupType(x8e4_29_getup)));
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCGetupCmd(pas::EGetupType(!x8e4_29_getup)));
|
||||
}
|
||||
} else if (x568_ == 2 &&
|
||||
x450_bodyController->GetBodyStateInfo().GetCurrentStateId() != pas::EAnimationState::Getup) {
|
||||
|
@ -777,7 +797,8 @@ void CFlaahgra::SetCollisionActorBounds(CStateManager& mgr, const std::unique_pt
|
|||
}
|
||||
}
|
||||
void CFlaahgra::UpdateScale(float t, float min, float max) {
|
||||
ModelData()->SetScale(zeus::skOne3f * (t * (max - min) + min));
|
||||
float scale = (t * (max - min) + min);
|
||||
ModelData()->SetScale(zeus::skOne3f * scale);
|
||||
}
|
||||
|
||||
float CFlaahgra::GetEndActionTime() {
|
||||
|
@ -838,7 +859,7 @@ void CFlaahgra::RattlePlayer(CStateManager& mgr, const zeus::CVector3f& vec) {
|
|||
}
|
||||
|
||||
void CFlaahgra::Faint(CStateManager& mgr, EStateMsg msg, float arg) {
|
||||
static const pas::ESeverity kSeverities[2] {pas::ESeverity::Zero, pas::ESeverity::One};
|
||||
static const pas::ESeverity kSeverities[2]{pas::ESeverity::Zero, pas::ESeverity::One};
|
||||
if (msg == EStateMsg::Activate) {
|
||||
x568_ = 0;
|
||||
x7d4_ = 0.f;
|
||||
|
@ -877,11 +898,8 @@ void CFlaahgra::Faint(CStateManager& mgr, EStateMsg msg, float arg) {
|
|||
|
||||
void CFlaahgra::Dead(CStateManager& mgr, EStateMsg msg, float) {
|
||||
if (msg == EStateMsg::Activate) {
|
||||
bool r29 = true;
|
||||
if (x450_bodyController->GetFallState() == pas::EFallState::Zero &&
|
||||
x450_bodyController->GetBodyStateInfo().GetCurrentStateId() == pas::EAnimationState::Fall)
|
||||
r29 = false;
|
||||
x568_ = r29;
|
||||
x568_ = (x450_bodyController->GetFallState() != pas::EFallState::Zero ||
|
||||
x450_bodyController->GetBodyStateInfo().GetCurrentStateId() == pas::EAnimationState::Fall);
|
||||
SendScriptMsgs(EScriptObjectState::CloseIn, mgr, EScriptObjectMessage::None);
|
||||
} else if (msg == EStateMsg::Update) {
|
||||
if (x568_ == 0) {
|
||||
|
@ -915,9 +933,8 @@ static const pas::ESeverity kStates1[5]{pas::ESeverity::Invalid, pas::ESeverity:
|
|||
pas::ESeverity::Two, pas::ESeverity::Invalid};
|
||||
|
||||
void CFlaahgra::Attack(CStateManager& mgr, EStateMsg msg, float arg) {
|
||||
static const pas::ESeverity kSeverity[5] {
|
||||
pas::ESeverity::Three, pas::ESeverity::Four, pas::ESeverity::One, pas::ESeverity::Zero, pas::ESeverity::Invalid
|
||||
};
|
||||
static const pas::ESeverity kSeverity[5]{pas::ESeverity::Three, pas::ESeverity::Four, pas::ESeverity::One,
|
||||
pas::ESeverity::Zero, pas::ESeverity::Invalid};
|
||||
|
||||
if (msg == EStateMsg::Activate) {
|
||||
x568_ = 0;
|
||||
|
@ -1016,6 +1033,7 @@ void CFlaahgra::Suck(CStateManager& mgr, EStateMsg msg, float) {
|
|||
x568_ = 0;
|
||||
x8e4_26_ = false;
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCGenerateCmd(pas::EGenerateType::Two));
|
||||
x784_ = x780_;
|
||||
} else if (msg == EStateMsg::Update) {
|
||||
if (x568_ == 0) {
|
||||
if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() == pas::EAnimationState::Getup)
|
||||
|
@ -1026,7 +1044,7 @@ void CFlaahgra::Suck(CStateManager& mgr, EStateMsg msg, float) {
|
|||
if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() != pas::EAnimationState::Getup)
|
||||
x568_ = 4;
|
||||
else if (x8e4_26_) {
|
||||
UpdateScale(x7c4_ > 0.f ? 1.f - (GetEndActionTime() / x7c4_) : 1.f, x56c_.x4_, x56c_.x0_);
|
||||
UpdateScale(x7c4_ > 0.0f ? 1.f - (GetEndActionTime() / x7c4_) : 1.f, x56c_.x4_, x56c_.x0_);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1037,8 +1055,44 @@ void CFlaahgra::Suck(CStateManager& mgr, EStateMsg msg, float) {
|
|||
x7a0_rightArmCollision->SetActive(mgr, false);
|
||||
}
|
||||
}
|
||||
void CFlaahgra::ProjectileAttack(CStateManager&, EStateMsg, float) {
|
||||
void CFlaahgra::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float) {
|
||||
if (msg == EStateMsg::Activate) {
|
||||
x568_ = 0;
|
||||
SendScriptMsgs(EScriptObjectState::Attack, mgr, EScriptObjectMessage::None);
|
||||
} else if (msg == EStateMsg::Update) {
|
||||
if (x568_ == 0) {
|
||||
if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() == pas::EAnimationState::ProjectileAttack) {
|
||||
x568_ = 2;
|
||||
} else {
|
||||
x7b4_ = 3;
|
||||
pas::ESeverity severity;
|
||||
if (x8e4_31_) {
|
||||
x7b4_ = 2;
|
||||
severity = pas::ESeverity::Six;
|
||||
} else if (mgr.GetPlayer().GetVelocity().magSquared() > 100.f) {
|
||||
if (mgr.GetPlayer().GetTransform().basis[0].magSquared() < 0.f) {
|
||||
x7b4_ = 1;
|
||||
severity = pas::ESeverity::Four;
|
||||
x72c_ = 0;
|
||||
} else {
|
||||
severity = pas::ESeverity::Three;
|
||||
x7b4_ = x72c_ = 0;
|
||||
}
|
||||
} else {
|
||||
severity = pas::ESeverity::Seven;
|
||||
}
|
||||
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(
|
||||
CBCProjectileAttackCmd(severity, mgr.GetPlayer().GetTranslation(), false));
|
||||
}
|
||||
} else if (x568_ == 2) {
|
||||
if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() != pas::EAnimationState::ProjectileAttack) {
|
||||
x568_ = 4;
|
||||
} else {
|
||||
x450_bodyController->GetCommandMgr().SetTargetVector(mgr.GetPlayer().GetTranslation() - GetTranslation());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void CFlaahgra::Cover(CStateManager& mgr, EStateMsg msg, float) {
|
||||
static pas::ESeverity severities[2]{pas::ESeverity::Eight, pas::ESeverity::Seven};
|
||||
|
@ -1054,7 +1108,7 @@ void CFlaahgra::Cover(CStateManager& mgr, EStateMsg msg, float) {
|
|||
else
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCMeleeAttackCmd(severities[x7b0_]));
|
||||
} else if (x568_ == 1) {
|
||||
if (TCastToConstPtr<CScriptWaypoint> wp = mgr.GetObjectById(x77c_)) {
|
||||
if (TCastToConstPtr<CActor> wp = mgr.GetObjectById(x77c_)) {
|
||||
zeus::CVector3f direction = wp->GetTranslation() - GetTranslation();
|
||||
if (zeus::CVector2f::getAngleDiff(GetTransform().basis[1].toVec2f(), direction.toVec2f()) >
|
||||
zeus::degToRad(15.f) &&
|
||||
|
@ -1069,7 +1123,7 @@ void CFlaahgra::Cover(CStateManager& mgr, EStateMsg msg, float) {
|
|||
} else if (x568_ == 2) {
|
||||
if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() != pas::EAnimationState::MeleeAttack)
|
||||
x568_ = 4;
|
||||
else if (TCastToConstPtr<CScriptWaypoint> wp = mgr.GetObjectById(x77c_)) {
|
||||
else if (TCastToConstPtr<CActor> wp = mgr.GetObjectById(x77c_)) {
|
||||
x450_bodyController->GetCommandMgr().SetTargetVector(wp->GetTranslation() - GetTranslation());
|
||||
}
|
||||
}
|
||||
|
@ -1083,9 +1137,28 @@ void CFlaahgra::Cover(CStateManager& mgr, EStateMsg msg, float) {
|
|||
x7b0_ ^= 1;
|
||||
}
|
||||
}
|
||||
void CFlaahgra::SpecialAttack(CStateManager&, EStateMsg, float) {}
|
||||
void CFlaahgra::SpecialAttack(CStateManager& mgr, EStateMsg msg, float) {
|
||||
if (msg == EStateMsg::Activate) {
|
||||
x568_ = 0;
|
||||
x8e5_24_ = false;
|
||||
x7b4_ = 3;
|
||||
SendScriptMsgs(EScriptObjectState::Attack, mgr, EScriptObjectMessage::None);
|
||||
} else if (msg == EStateMsg::Update) {
|
||||
if (x568_ == 0) {
|
||||
if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() == pas::EAnimationState::ProjectileAttack) {
|
||||
x568_ = 2;
|
||||
x8e4_30_ = true;
|
||||
} else {
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(
|
||||
CBCProjectileAttackCmd(pas::ESeverity::Eight, mgr.GetPlayer().GetTranslation(), false));
|
||||
}
|
||||
} else if (x568_ == 2) {
|
||||
if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() != pas::EAnimationState::ProjectileAttack) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
bool CFlaahgra::CoverCheck(CStateManager& mgr, float) {
|
||||
if (x7f8_ < 0 && x7bc_ > 0.f)
|
||||
if (x7f8_ <= 0 && x7bc_ > 0.f)
|
||||
return false;
|
||||
|
||||
for (TUniqueId id : x770_mirrorWaypoints) {
|
||||
|
@ -1103,11 +1176,10 @@ TUniqueId CFlaahgra::GetMirrorNearestPlayer(CStateManager& mgr) {
|
|||
|
||||
TUniqueId nearId = kInvalidUniqueId;
|
||||
for (TUniqueId id : x770_mirrorWaypoints) {
|
||||
if (TCastToConstPtr<CScriptWaypoint> wp = mgr.GetObjectById(id)) {
|
||||
if (TCastToConstPtr<CActor> wp = mgr.GetObjectById(id)) {
|
||||
if (!wp->GetActive())
|
||||
continue;
|
||||
|
||||
|
||||
if ((wp->GetTranslation() - playerPos).magSquared() > -1.f)
|
||||
nearId = id;
|
||||
}
|
||||
|
@ -1116,22 +1188,37 @@ TUniqueId CFlaahgra::GetMirrorNearestPlayer(CStateManager& mgr) {
|
|||
return nearId;
|
||||
}
|
||||
|
||||
void CFlaahgra::Enraged(CStateManager&, EStateMsg msg, float) {
|
||||
if (msg == EStateMsg::Activate) {
|
||||
x568_ = 0;
|
||||
} else if (msg == EStateMsg::Update) {
|
||||
if (x568_ == 0) {
|
||||
if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() == pas::EAnimationState::Taunt)
|
||||
x568_ = 2;
|
||||
else
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCTauntCmd(pas::ETauntType::Zero));
|
||||
} else if (x568_ == 2 && x450_bodyController->GetBodyStateInfo().GetCurrentStateId() != pas::EAnimationState::Taunt)
|
||||
x568_ = 4;
|
||||
} else if (msg == EStateMsg::Deactivate) {
|
||||
x7d0_ = 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
CFlaahgraPlants::CFlaahgraPlants(const TToken<CGenDescription>& genDesc, const CActorParameters& actParms,
|
||||
TUniqueId uid, TAreaId aId, TUniqueId owner, const zeus::CTransform& xf,
|
||||
const CDamageInfo& dInfo, const zeus::CVector3f& extents)
|
||||
: CActor(uid, true, "Flaahgra Plants"sv, CEntityInfo(aId, NullConnectionList), xf, CModelData::CModelDataNull(),
|
||||
CMaterialList(EMaterialTypes::Projectile), actParms, kInvalidUniqueId)
|
||||
, xe8_elementGen(new CElementGen(genDesc))
|
||||
, xf0_ownerId(owner)
|
||||
, x130_obbox(xf, extents) {
|
||||
xe8_elementGen->SetGlobalOrientation(xf.getRotation());
|
||||
xe8_elementGen->SetGlobalTranslation(xf.origin);
|
||||
: CActor(uid, true, "Flaahgra Plants"sv, CEntityInfo(aId, NullConnectionList), xf, CModelData::CModelDataNull(),
|
||||
CMaterialList(EMaterialTypes::Projectile), actParms, kInvalidUniqueId)
|
||||
, xe8_elementGen(new CElementGen(genDesc))
|
||||
, xf0_ownerId(owner)
|
||||
, x130_obbox(xf, extents) {
|
||||
xe8_elementGen->SetOrientation(xf.getRotation());
|
||||
xe8_elementGen->SetTranslation(xf.origin);
|
||||
xe8_elementGen->SetModelsUseLights(true);
|
||||
x110_aabox = {x130_obbox.calculateAABox(xf)};
|
||||
}
|
||||
|
||||
void CFlaahgraPlants::Accept(IVisitor& visitor) {
|
||||
visitor.Visit(this);
|
||||
}
|
||||
void CFlaahgraPlants::Accept(IVisitor& visitor) { visitor.Visit(this); }
|
||||
|
||||
void CFlaahgraPlants::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) {
|
||||
CActor::AcceptScriptMsg(msg, uid, mgr);
|
||||
|
|
|
@ -200,7 +200,7 @@ public:
|
|||
bool AnimOver(CStateManager&, float) { return x568_ == 4; }
|
||||
bool AIStage(CStateManager&, float arg) { return x780_ == u32(arg); }
|
||||
bool HitSomething(CStateManager&, float arg) { return x7d0_ > 0.f; }
|
||||
bool OffLine(CStateManager&, float) { return (!x8e5_29_ && !x8e5_28_); }
|
||||
bool OffLine(CStateManager&, float) { return (x8e5_29_ && x8e5_28_); }
|
||||
bool ShouldTurn(CStateManager&, float);
|
||||
bool ShouldAttack(CStateManager&, float);
|
||||
bool BreakAttack(CStateManager&, float) { return x7d4_ >= x56c_.xc_ && !x8e4_29_getup; }
|
||||
|
@ -223,6 +223,7 @@ public:
|
|||
void ProjectileAttack(CStateManager&, EStateMsg, float);
|
||||
void Cover(CStateManager&, EStateMsg, float);
|
||||
void SpecialAttack(CStateManager&, EStateMsg, float);
|
||||
void Enraged(CStateManager&, EStateMsg, float);
|
||||
|
||||
};
|
||||
}
|
|
@ -17,11 +17,11 @@
|
|||
|
||||
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));
|
||||
const float CParasite::flt_805A8FB0 = 2.f * std::sqrt(2.5f / CPhysicsActor::GravityConstant());
|
||||
const float CParasite::skAttackVelocity = 15.f / 2.f * (std::sqrt(2.5f / CPhysicsActor::GravityConstant()));
|
||||
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);
|
||||
const float CParasite::flt_805A8FB8 = 2.f * std::sqrt(2.5f / CPhysicsActor::GravityConstant());
|
||||
const float CParasite::skRetreatVelocity = 3.f / 2.f * std::sqrt(2.5f / CPhysicsActor::GravityConstant());
|
||||
|
||||
CParasite::CParasite(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo& info,
|
||||
const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo, EBodyType bodyType,
|
||||
|
|
|
@ -142,7 +142,7 @@ void CPuddleToadGamma::ShootPlayer(CStateManager& mgr, float speed) {
|
|||
for (TUniqueId id : nearList) {
|
||||
if (TCastToPtr<CBomb> bomb = mgr.ObjectById(id)) {
|
||||
bomb->SetVelocityWR((mgr.GetActiveRandom()->Float() * 5.f + 20.f) * shootDir);
|
||||
bomb->SetConstantAccelerationWR({0.f, 0.f, -24.525f});
|
||||
bomb->SetConstantAccelerationWR({0.f, 0.f, -CPhysicsActor::GravityConstant()});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,13 +2,37 @@
|
|||
#include "CStateManager.hpp"
|
||||
#include "World/CWorld.hpp"
|
||||
#include "World/CGameArea.hpp"
|
||||
#include "World/CPatternedInfo.hpp"
|
||||
#include "World/CPlayer.hpp"
|
||||
#include "Weapon/CBomb.hpp"
|
||||
#include "TCastTo.hpp"
|
||||
|
||||
namespace urde::MP1 {
|
||||
const CDamageVulnerability CTryclops::skVulnerabilities = CDamageVulnerability(
|
||||
EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect,
|
||||
EVulnerability::Deflect, EVulnerability::Normal, EVulnerability::Deflect, EVulnerability::Deflect,
|
||||
EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect,
|
||||
EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EDeflectType::Two);
|
||||
|
||||
CTryclops::CTryclops(urde::TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf,
|
||||
urde::CModelData&& mData, const urde::CPatternedInfo& pInfo,
|
||||
const urde::CActorParameters& actParms, float, float, float, float)
|
||||
const urde::CActorParameters& actParms, float f1, float f2, float f3, float f4)
|
||||
: CPatterned(ECharacter::Tryclops, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo,
|
||||
EMovementType::Ground, EColliderType::One, EBodyType::BiPedal, actParms, EKnockBackVariant::Small) {}
|
||||
EMovementType::Ground, EColliderType::One, EBodyType::BiPedal, actParms, EKnockBackVariant::Small)
|
||||
, x568_pathFindSearch(nullptr, 1, pInfo.GetPathfindingIndex(), 1.f, 1.f)
|
||||
, x67c_(f1)
|
||||
, x680_(std::cos(zeus::degToRad(0.5f * f2)))
|
||||
, x684_(f3)
|
||||
, x688_(f4)
|
||||
, x698_24_(false)
|
||||
, x698_25_(false)
|
||||
, x698_26_(false)
|
||||
, x698_27_dizzy(false) {
|
||||
CreateShadow(false);
|
||||
MakeThermalColdAndHot();
|
||||
x460_knockBackController.SetAutoResetImpulse(false);
|
||||
x328_30_lookAtDeathDir = false;
|
||||
}
|
||||
|
||||
void CTryclops::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) {
|
||||
CPatterned::AcceptScriptMsg(msg, uid, mgr);
|
||||
|
@ -16,7 +40,417 @@ void CTryclops::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateM
|
|||
if (msg == EScriptObjectMessage::Registered) {
|
||||
x450_bodyController->Activate(mgr);
|
||||
} else if (msg == EScriptObjectMessage::InitializedInArea) {
|
||||
//x568_pathFindSearch.SetArea(mgr.GetWorld()->GetAreaAlways(GetAreaIdAlways())->GetPostConstructed()->x10bc_pathArea);
|
||||
x568_pathFindSearch.SetArea(mgr.GetWorld()->GetAreaAlways(GetAreaIdAlways())->GetPostConstructed()->x10bc_pathArea);
|
||||
}
|
||||
}
|
||||
|
||||
void CTryclops::Think(float dt, CStateManager& mgr) {
|
||||
CPatterned::Think(dt, mgr);
|
||||
|
||||
if (x400_25_alive && x68c_ > 0.f)
|
||||
x68c_ -= dt;
|
||||
|
||||
if (mgr.GetPlayer().GetAttachedActor() != GetUniqueId() || x698_27_dizzy)
|
||||
return;
|
||||
|
||||
x698_27_dizzy = (mgr.GetPlayer().GetAttachedActorStruggle() == 1.f && sub8025dbd0(mgr));
|
||||
}
|
||||
|
||||
void CTryclops::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& poi, EUserEventType type, float dt) {
|
||||
|
||||
switch (type) {
|
||||
case EUserEventType::Projectile:
|
||||
if (x694_bombId == kInvalidUniqueId) {
|
||||
LaunchPlayer(mgr, GetLctrTransform(poi.GetLocatorName()), (x698_27_dizzy ? 5.f : x688_));
|
||||
} else {
|
||||
DragBomb(mgr, GetLctrTransform(poi.GetLocatorName()));
|
||||
}
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
CPatterned::DoUserAnimEvent(mgr, poi, type, dt);
|
||||
}
|
||||
|
||||
void CTryclops::Death(CStateManager& mgr, const zeus::CVector3f& vec, EScriptObjectState state) {
|
||||
if (x400_25_alive) {
|
||||
CPlayer& player = mgr.GetPlayer();
|
||||
if (player.GetAttachedActor() == GetUniqueId()) {
|
||||
player.SetLeaveMorphBallAllowed(true);
|
||||
player.AddMaterial(EMaterialTypes::Solid, mgr);
|
||||
player.DetachActorFromPlayer();
|
||||
} else if (x694_bombId != kInvalidUniqueId) {
|
||||
if (TCastToPtr<CBomb> bomb = mgr.ObjectById(x694_bombId)) {
|
||||
bomb->SetFuseDisabled(false);
|
||||
bomb->SetIsBeingDragged(false);
|
||||
}
|
||||
x694_bombId = kInvalidUniqueId;
|
||||
}
|
||||
}
|
||||
|
||||
CPatterned::Death(mgr, vec, state);
|
||||
}
|
||||
|
||||
void CTryclops::Patrol(CStateManager& mgr, EStateMsg msg, float arg) {
|
||||
CPatterned::Patrol(mgr, msg, arg);
|
||||
|
||||
if (msg == EStateMsg::Activate) {
|
||||
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed);
|
||||
} else if (msg == EStateMsg::Update) {
|
||||
ApplySeparation(mgr);
|
||||
}
|
||||
}
|
||||
|
||||
void CTryclops::PathFind(CStateManager& mgr, EStateMsg msg, float arg) {
|
||||
CPatterned::PathFind(mgr, msg, arg);
|
||||
|
||||
zeus::CVector3f front = GetTransform().basis[1];
|
||||
if (front.dot(x450_bodyController->GetCommandMgr().GetMoveVector()) < 0.f && front.canBeNormalized()) {
|
||||
x450_bodyController->GetCommandMgr().ClearLocomotionCmds();
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(front.normalized(), {}, 1.f));
|
||||
}
|
||||
ApplySeparation(mgr);
|
||||
}
|
||||
|
||||
void CTryclops::SelectTarget(CStateManager&, EStateMsg, float) {}
|
||||
|
||||
void CTryclops::TargetPatrol(CStateManager&, EStateMsg, float) {}
|
||||
|
||||
void CTryclops::TargetPlayer(CStateManager&, EStateMsg, float) {}
|
||||
|
||||
void CTryclops::TargetCover(CStateManager& mgr, EStateMsg msg, float) {
|
||||
if (msg == EStateMsg::Update) {
|
||||
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed);
|
||||
if (x694_bombId == kInvalidUniqueId)
|
||||
return;
|
||||
|
||||
if (TCastToConstPtr<CBomb> bomb = mgr.GetObjectById(x694_bombId))
|
||||
SetDestPos(bomb->GetTranslation());
|
||||
else
|
||||
x694_bombId = kInvalidUniqueId;
|
||||
}
|
||||
}
|
||||
|
||||
void CTryclops::Attack(CStateManager&, EStateMsg, float) {}
|
||||
void CTryclops::JumpBack(CStateManager&, EStateMsg, float) {}
|
||||
void CTryclops::Shuffle(CStateManager& mgr, EStateMsg msg, float arg) { PathFind(mgr, msg, arg); }
|
||||
void CTryclops::TurnAround(CStateManager&, EStateMsg, float) {}
|
||||
void CTryclops::Crouch(CStateManager& mgr, EStateMsg msg, float) {
|
||||
if (msg == EStateMsg::Activate) {
|
||||
if (TCastToConstPtr<CActor> wp =
|
||||
mgr.GetObjectById(GetWaypointForState(mgr, EScriptObjectState::Retreat, EScriptObjectMessage::Follow))) {
|
||||
SetDestPos(wp->GetTranslation());
|
||||
}
|
||||
|
||||
mgr.GetPlayer().Stop();
|
||||
mgr.GetPlayer().RemoveMaterial(EMaterialTypes::Solid, mgr);
|
||||
SendScriptMsgs(EScriptObjectState::Inside, mgr, EScriptObjectMessage::None);
|
||||
mgr.GetPlayer().AttachActorToPlayer(GetUniqueId(), true);
|
||||
mgr.GetPlayer().SetLeaveMorphBallAllowed(false);
|
||||
mgr.GetPlayer().GetMorphBall()->DisableHalfPipeStatus();
|
||||
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Combat);
|
||||
} else if (msg == EStateMsg::Update) {
|
||||
DragPlayer(mgr, GetLctrTransform("ballGrab_locator"sv).origin);
|
||||
} else if (msg == EStateMsg::Deactivate) {
|
||||
if (mgr.GetPlayer().GetAttachedActor() == GetUniqueId())
|
||||
mgr.GetPlayer().DetachActorFromPlayer();
|
||||
mgr.GetPlayer().SetLeaveMorphBallAllowed(true);
|
||||
mgr.GetPlayer().AddMaterial(EMaterialTypes::Solid, mgr);
|
||||
}
|
||||
}
|
||||
|
||||
void CTryclops::GetUp(CStateManager& mgr, EStateMsg msg, float) {
|
||||
if (msg == EStateMsg::Activate) {
|
||||
x32c_animState = EAnimState::Ready;
|
||||
x698_24_ = false;
|
||||
} else if (msg == EStateMsg::Update) {
|
||||
TryCommand(mgr, pas::EAnimationState::MeleeAttack, &CPatterned::TryMeleeAttack, 1);
|
||||
if (!x698_24_) {
|
||||
GrabBomb(mgr);
|
||||
}
|
||||
} else if (msg == EStateMsg::Deactivate) {
|
||||
x32c_animState = EAnimState::NotReady;
|
||||
}
|
||||
}
|
||||
|
||||
void CTryclops::Suck(CStateManager& mgr, EStateMsg msg, float arg) {
|
||||
if (msg == EStateMsg::Activate) {
|
||||
mgr.GetPlayer().SetLeaveMorphBallAllowed(false);
|
||||
mgr.GetPlayer().GetMorphBall()->DisableHalfPipeStatus();
|
||||
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Internal6);
|
||||
} else if (msg == EStateMsg::Update) {
|
||||
SuckPlayer(mgr, arg);
|
||||
} else if (msg == EStateMsg::Deactivate) {
|
||||
mgr.GetPlayer().SetLeaveMorphBallAllowed(true);
|
||||
mgr.GetPlayer().AddMaterial(EMaterialTypes::Solid, mgr);
|
||||
}
|
||||
}
|
||||
|
||||
void CTryclops::Cover(CStateManager&, EStateMsg, float) {}
|
||||
void CTryclops::Approach(CStateManager&, EStateMsg, float) {}
|
||||
void CTryclops::PathFindEx(CStateManager& mgr, EStateMsg msg, float arg) {
|
||||
CPatterned::PathFind(mgr, msg, arg);
|
||||
ApplySeparation(mgr);
|
||||
|
||||
CPlayer& player = mgr.GetPlayer();
|
||||
if (msg == EStateMsg::Activate) {
|
||||
player.Stop();
|
||||
player.RemoveMaterial(EMaterialTypes::Solid, mgr);
|
||||
player.GetMorphBall()->DisableHalfPipeStatus();
|
||||
player.AttachActorToPlayer(GetUniqueId(), true);
|
||||
} else if (msg == EStateMsg::Update) {
|
||||
DragPlayer(mgr, GetLctrTransform("ballGrab_locator"sv).origin);
|
||||
}
|
||||
}
|
||||
void CTryclops::Dizzy(CStateManager&, EStateMsg, float) {}
|
||||
bool CTryclops::InAttackPosition(CStateManager& mgr, float) {
|
||||
if (mgr.GetPlayer().GetMorphballTransitionState() != CPlayer::EPlayerMorphBallState::Morphed)
|
||||
return false;
|
||||
|
||||
CPlayer& player = mgr.GetPlayer();
|
||||
return sub80260180(player.GetTranslation(),
|
||||
player.GetTranslation() + zeus::CVector3f(0.f, 0.f, player.GetMorphBall()->GetBallRadius()),
|
||||
player.GetBoundingBox(), mgr);
|
||||
}
|
||||
|
||||
bool CTryclops::InRange(CStateManager& mgr, float) {
|
||||
if (x694_bombId != kInvalidUniqueId) {
|
||||
if (TCastToConstPtr<CBomb> bomb = mgr.GetObjectById(x694_bombId)) {
|
||||
return sub80260180(bomb->GetTranslation(), bomb->GetTranslation(), *bomb->GetTouchBounds(), mgr);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CTryclops::InMaxRange(CStateManager& mgr, float) {
|
||||
if (x694_bombId != kInvalidUniqueId)
|
||||
return true;
|
||||
|
||||
rstl::reserved_vector<TUniqueId, 1024> nearList;
|
||||
|
||||
float dectRange = x3bc_detectionRange * x3bc_detectionRange;
|
||||
float dectRangeHeight = x3c0_detectionHeightRange * x3c0_detectionHeightRange;
|
||||
mgr.BuildNearList(nearList, {GetTranslation() - x3bc_detectionRange, GetTranslation() + x3bc_detectionRange},
|
||||
CMaterialFilter::MakeInclude({EMaterialTypes::Bomb}), this);
|
||||
|
||||
x694_bombId = kInvalidUniqueId;
|
||||
|
||||
for (TUniqueId uid : nearList) {
|
||||
if (TCastToConstPtr<CBomb> bomb = mgr.GetObjectById(uid)) {
|
||||
if (!bomb->IsBeingDragged()) {
|
||||
float dist = (bomb->GetTranslation() - GetTranslation()).magSquared();
|
||||
float height = (bomb->GetTranslation().z() - GetTranslation().z());
|
||||
if (dist < dectRange && (height * height) < dectRangeHeight) {
|
||||
if (x568_pathFindSearch.OnPath(bomb->GetTranslation()) == CPathFindSearch::EResult::Success) {
|
||||
dectRange = dist;
|
||||
x694_bombId = bomb->GetUniqueId();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (x694_bombId != kInvalidUniqueId) {
|
||||
if (TCastToPtr<CBomb> bomb = mgr.ObjectById(x694_bombId)) {
|
||||
bomb->SetFuseDisabled(true);
|
||||
bomb->SetIsBeingDragged(true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CTryclops::InDetectionRange(CStateManager& mgr, float arg) {
|
||||
CPlayer& player = mgr.GetPlayer();
|
||||
|
||||
if (player.GetMorphballTransitionState() != CPlayer::EPlayerMorphBallState::Morphed ||
|
||||
player.GetAttachedActor() != kInvalidUniqueId || x68c_ > 0.f || !CPatterned::InDetectionRange(mgr, arg))
|
||||
return false;
|
||||
|
||||
return x568_pathFindSearch.OnPath(player.GetBallPosition()) == CPathFindSearch::EResult::Success;
|
||||
}
|
||||
|
||||
bool CTryclops::SpotPlayer(CStateManager& mgr, float) {
|
||||
if (x694_bombId != kInvalidUniqueId) {
|
||||
|
||||
CPlayer& player = mgr.GetPlayer();
|
||||
if (TCastToPtr<CBomb> bomb = mgr.ObjectById(x694_bombId)) {
|
||||
if (player.GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed) {
|
||||
bool isPlayerCloser = (player.GetTranslation() - GetTranslation()).magSquared() <
|
||||
(bomb->GetTranslation() - GetTranslation()).magSquared();
|
||||
if (isPlayerCloser) {
|
||||
bomb->SetFuseDisabled(false);
|
||||
bomb->SetIsBeingDragged(false);
|
||||
x694_bombId = kInvalidUniqueId;
|
||||
}
|
||||
return isPlayerCloser;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
bool CTryclops::InPosition(CStateManager& mgr, float arg) {
|
||||
if (x694_bombId != kInvalidUniqueId) {
|
||||
if (TCastToConstPtr<CBomb> bomb = mgr.GetObjectById(x694_bombId)) {
|
||||
return sub802600c8(bomb->GetTranslation(), arg);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CTryclops::HearShot(CStateManager& mgr, float) {
|
||||
x698_26_ = false;
|
||||
if (x694_bombId != kInvalidUniqueId) {
|
||||
if (TCastToConstPtr<CBomb>(mgr.GetObjectById(x694_bombId))) {
|
||||
x698_26_ = true;
|
||||
return false;
|
||||
} else
|
||||
x694_bombId = kInvalidUniqueId;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CTryclops::CoverBlown(CStateManager&, float) {
|
||||
return x568_pathFindSearch.OnPath(GetTranslation()) != CPathFindSearch::EResult::InvalidArea;
|
||||
}
|
||||
|
||||
bool CTryclops::Inside(CStateManager& mgr, float arg) {
|
||||
const zeus::CTransform xf = mgr.GetPlayer().GetTransform();
|
||||
x64c_ = xf.getRotation();
|
||||
|
||||
return sub802600c8(xf.origin + zeus::CVector3f(0.f, 0.f, mgr.GetPlayer().GetMorphBall()->GetBallRadius()), arg);
|
||||
}
|
||||
|
||||
bool CTryclops::ShouldRetreat(CStateManager& mgr, float) {
|
||||
if (TCastToConstPtr<CActor> wp =
|
||||
mgr.GetObjectById(GetWaypointForState(mgr, EScriptObjectState::Modify, EScriptObjectMessage::Next))) {
|
||||
SetDestPos(wp->GetTranslation());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CTryclops::IsDizzy(CStateManager&, float) { return x698_27_dizzy; }
|
||||
|
||||
void CTryclops::LaunchPlayer(CStateManager& mgr, const zeus::CTransform& xf, float f1) {
|
||||
CPlayer& player = mgr.GetPlayer();
|
||||
player.SetLeaveMorphBallAllowed(true);
|
||||
|
||||
if (player.GetMorphballTransitionState() != CPlayer::EPlayerMorphBallState::Morphed)
|
||||
return;
|
||||
|
||||
x698_24_ = true;
|
||||
x68c_ = 1.5f;
|
||||
player.Stop();
|
||||
zeus::CTransform tmpXf = (xf * x64c_);
|
||||
tmpXf.origin += zeus::CVector3f(0.f, 0.f, -0.5f);
|
||||
player.Teleport(xf, mgr, false);
|
||||
player.ApplyImpulseWR(f1 * (player.GetMass() * xf.basis[1].normalized()), zeus::CAxisAngle());
|
||||
player.SetMoveState(CPlayer::EPlayerMovementState::ApplyJump, mgr);
|
||||
player.AddMaterial(EMaterialTypes::Solid, mgr);
|
||||
mgr.ApplyDamage(GetUniqueId(), player.GetUniqueId(), GetUniqueId(), GetContactDamage(),
|
||||
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {}), {});
|
||||
}
|
||||
|
||||
void CTryclops::DragBomb(CStateManager& mgr, const zeus::CTransform& xf) {
|
||||
if (x694_bombId != kInvalidUniqueId) {
|
||||
if (TCastToPtr<CBomb> bomb = mgr.ObjectById(x694_bombId)) {
|
||||
bomb->SetVelocityWR((5.f * mgr.GetActiveRandom()->Float() + 20.f) * xf.basis[1].normalized());
|
||||
bomb->SetConstantAccelerationWR({0.f, 0.f, -CPhysicsActor::GravityConstant()});
|
||||
}
|
||||
}
|
||||
|
||||
x698_26_ = false;
|
||||
x698_24_ = true;
|
||||
x694_bombId = kInvalidUniqueId;
|
||||
}
|
||||
|
||||
void CTryclops::ApplySeparation(CStateManager& mgr) {
|
||||
for (CEntity* ent : mgr.GetListeningAiObjectList()) {
|
||||
if (TCastToPtr<CAi> ai = ent) {
|
||||
if (ai == this || ai->GetAreaIdAlways() != GetAreaId())
|
||||
continue;
|
||||
|
||||
zeus::CVector3f sep = x45c_steeringBehaviors.Separation(*this, ai->GetTranslation(), 8.f);
|
||||
if (sep.x() != 0.f && sep.y() != 0.f && sep.z() != 0.f)
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(sep, {}, 1.f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CTryclops::GrabBomb(CStateManager& mgr) {
|
||||
if (TCastToPtr<CBomb> bomb = mgr.ObjectById(x694_bombId)) {
|
||||
zeus::CTransform grabLctr = GetLctrTransform("ballGrab_locator"sv);
|
||||
grabLctr.origin += zeus::CVector3f(0.f, 0.f, -3.f);
|
||||
bomb->SetTransform(grabLctr);
|
||||
}
|
||||
}
|
||||
|
||||
void CTryclops::DragPlayer(CStateManager& mgr, const zeus::CVector3f& locOrig) {
|
||||
CPlayer& player = mgr.GetPlayer();
|
||||
player.Stop();
|
||||
player.RemoveMaterial(EMaterialTypes::Solid, mgr);
|
||||
zeus::CTransform xf = GetLctrTransform("ballGrab_locator"sv) * x64c_;
|
||||
xf.origin += {0.f, 0.f, -.5f};
|
||||
player.SetTransform(xf);
|
||||
}
|
||||
|
||||
bool CTryclops::sub802600c8(const zeus::CVector3f& vec, float arg) {
|
||||
return (vec - GetLctrTransform("ballGrab_locator"sv).origin).magSquared() <= arg;
|
||||
}
|
||||
|
||||
bool CTryclops::sub80260180(const zeus::CVector3f& vec1, const zeus::CVector3f& vec2, const zeus::CAABox& bounds,
|
||||
CStateManager& mgr) {
|
||||
|
||||
if (bounds.intersects(GetBoundingBox()))
|
||||
return true;
|
||||
|
||||
zeus::CTransform xf = GetLctrTransform("ballGrab_locator"sv);
|
||||
zeus::CVector3f tmpVec2 = vec2 - (xf.origin - (1.f * GetTransform().basis[1]));
|
||||
float f28 = tmpVec2.normalized().dot(GetTransform().basis[1]);
|
||||
zeus::CVector3f tmpVec4 = (vec1 - (xf.origin - (4.f * GetTransform().basis[1]))).normalized();
|
||||
float f30 = tmpVec4.dot(GetTransform().basis[1]);
|
||||
float f29 = tmpVec2.magnitude();
|
||||
|
||||
if (f29 > 2.f) {
|
||||
CRayCastResult res = mgr.RayStaticIntersection(
|
||||
xf.origin, (1.f / f29) * tmpVec2, f29 - mgr.GetPlayer().GetMorphBall()->GetBallRadius(),
|
||||
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {EMaterialTypes::Character, EMaterialTypes::Player,
|
||||
EMaterialTypes::ProjectilePassthrough}));
|
||||
if (res.IsValid())
|
||||
return false;
|
||||
}
|
||||
|
||||
return !(f29 >= x684_ || f28 <= 0.f || f30 <= x680_);
|
||||
}
|
||||
|
||||
void CTryclops::SuckPlayer(CStateManager& mgr, float arg) {
|
||||
if (mgr.GetPlayer().GetMorphballTransitionState() != CPlayer::EPlayerMorphBallState::Morphed)
|
||||
return;
|
||||
|
||||
CPlayer& player = mgr.GetPlayer();
|
||||
zeus::CTransform xf = GetLctrTransform("ballGrab_locator"sv);
|
||||
zeus::CVector3f diff = (player.GetTranslation() - xf.origin);
|
||||
float diffMag = diff.magnitude();
|
||||
if (diffMag < 3.f) {
|
||||
player.Stop();
|
||||
AttractPlayer(mgr, xf.origin, arg);
|
||||
} else {
|
||||
player.ApplyForceWR(((x67c_ * (x684_ / (diffMag * diffMag))) * (player.GetMass() * -diff)), {});
|
||||
}
|
||||
}
|
||||
|
||||
void CTryclops::AttractPlayer(CStateManager& mgr, const zeus::CVector3f& dest, float arg) {
|
||||
CPlayer& player = mgr.GetPlayer();
|
||||
const float ballRad = player.GetMorphBall()->GetBallRadius();
|
||||
player.SetVelocityWR(1.f / (2.f * arg) *
|
||||
(dest - (player.GetTranslation() + zeus::CVector3f(0.f, 0.f, ballRad))).normalized());
|
||||
}
|
||||
|
||||
} // namespace urde::MP1
|
|
@ -1,14 +1,90 @@
|
|||
#pragma once
|
||||
|
||||
#include "World/CPatterned.hpp"
|
||||
#include "World/CPathFindSearch.hpp"
|
||||
|
||||
namespace urde::MP1 {
|
||||
class CTryclops : public CPatterned {
|
||||
|
||||
static const CDamageVulnerability skVulnerabilities;
|
||||
CPathFindSearch x568_pathFindSearch;
|
||||
zeus::CTransform x64c_;
|
||||
float x67c_;
|
||||
float x680_;
|
||||
float x684_;
|
||||
float x688_;
|
||||
float x68c_ = 0.f;
|
||||
u32 x690_ = 0;
|
||||
TUniqueId x694_bombId = kInvalidUniqueId;
|
||||
TUniqueId x696_ = kInvalidUniqueId;
|
||||
bool x698_24_ : 1;
|
||||
bool x698_25_ : 1;
|
||||
bool x698_26_ : 1;
|
||||
bool x698_27_dizzy : 1;
|
||||
bool sub8025dbd0(CStateManager&) { return false; }
|
||||
void LaunchPlayer(CStateManager& mgr, const zeus::CTransform& xf, float);
|
||||
void DragBomb(CStateManager& mgr, const zeus::CTransform& xf);
|
||||
void ApplySeparation(CStateManager&);
|
||||
void GrabBomb(CStateManager& mgr);
|
||||
void DragPlayer(CStateManager& mgr, const zeus::CVector3f& locOrig);
|
||||
bool sub802600c8(const zeus::CVector3f&, float);
|
||||
bool sub80260180(const zeus::CVector3f&, const zeus::CVector3f&, const zeus::CAABox&, CStateManager&);
|
||||
void SuckPlayer(CStateManager& mgr, float);
|
||||
void AttractPlayer(CStateManager& mgr, const zeus::CVector3f& dest, float);
|
||||
|
||||
public:
|
||||
DEFINE_PATTERNED(Tryclops)
|
||||
CTryclops(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, CModelData&&,
|
||||
const CPatternedInfo&, const CActorParameters&, float, float, float, float);
|
||||
|
||||
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
|
||||
void Think(float, CStateManager&);
|
||||
const CDamageVulnerability* GetDamageVulnerability() const {
|
||||
if (x698_26_)
|
||||
return CAi::GetDamageVulnerability();
|
||||
|
||||
return &skVulnerabilities;
|
||||
}
|
||||
|
||||
const CDamageVulnerability* GetDamageVulnerability(const zeus::CVector3f&, const zeus::CVector3f&,
|
||||
const CDamageInfo&) const {
|
||||
if (x698_26_)
|
||||
return CAi::GetDamageVulnerability();
|
||||
|
||||
return &skVulnerabilities;
|
||||
}
|
||||
|
||||
void DoUserAnimEvent(CStateManager&, const CInt32POINode&, EUserEventType, float);
|
||||
void Death(CStateManager&, const zeus::CVector3f&, EScriptObjectState);
|
||||
bool IsListening() const { return true; }
|
||||
void Patrol(CStateManager&, EStateMsg, float);
|
||||
void PathFind(CStateManager&, EStateMsg, float);
|
||||
void SelectTarget(CStateManager&, EStateMsg, float);
|
||||
void TargetPatrol(CStateManager&, EStateMsg, float);
|
||||
void TargetPlayer(CStateManager&, EStateMsg, float);
|
||||
void TargetCover(CStateManager&, EStateMsg, float);
|
||||
void Attack(CStateManager&, EStateMsg, float);
|
||||
void JumpBack(CStateManager&, EStateMsg, float);
|
||||
void Shuffle(CStateManager&, EStateMsg, float);
|
||||
void TurnAround(CStateManager&, EStateMsg, float);
|
||||
void Crouch(CStateManager&, EStateMsg, float);
|
||||
void GetUp(CStateManager&, EStateMsg, float);
|
||||
void Suck(CStateManager&, EStateMsg, float);
|
||||
void Cover(CStateManager&, EStateMsg, float);
|
||||
void Approach(CStateManager&, EStateMsg, float);
|
||||
void PathFindEx(CStateManager&, EStateMsg, float);
|
||||
void Dizzy(CStateManager&, EStateMsg, float);
|
||||
bool InAttackPosition(CStateManager&, float);
|
||||
bool InRange(CStateManager&, float);
|
||||
bool InMaxRange(CStateManager&, float);
|
||||
bool InDetectionRange(CStateManager&, float);
|
||||
bool SpotPlayer(CStateManager&, float);
|
||||
bool InPosition(CStateManager&, float);
|
||||
bool HearShot(CStateManager&, float);
|
||||
bool CoverBlown(CStateManager&, float);
|
||||
bool Inside(CStateManager&, float);
|
||||
bool ShouldRetreat(CStateManager&, float);
|
||||
bool IsDizzy(CStateManager&, float);
|
||||
CPathFindSearch* GetSearchPath() { return &x568_pathFindSearch; }
|
||||
};
|
||||
} // namespace urde::MP1
|
||||
|
|
|
@ -24,9 +24,9 @@ CBomb::CBomb(const TCachedToken<CGenDescription>& particle1, const TCachedToken<
|
|||
new CElementGen(particle1, CElementGen::EModelOrientationType::Normal, CElementGen::EOptionalSystemFlags::One))
|
||||
, x184_particle2(
|
||||
new CElementGen(particle2, CElementGen::EModelOrientationType::Normal, CElementGen::EOptionalSystemFlags::One))
|
||||
, x18c_(particle2.GetObj())
|
||||
, x18c_particle2Obj(particle2.GetObj())
|
||||
, x190_24_isNotDetonated(true)
|
||||
, x190_25_(false)
|
||||
, x190_25_beingDragged(false)
|
||||
, x190_26_disableFuse(false) {
|
||||
x180_particle1->SetGlobalTranslation(xf.origin);
|
||||
x184_particle2->SetGlobalTranslation(xf.origin);
|
||||
|
@ -40,7 +40,7 @@ void CBomb::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManag
|
|||
x188_lightId = mgr.AllocateUniqueId();
|
||||
CGameLight* gameLight = new CGameLight(x188_lightId, GetAreaIdAlways(), false,
|
||||
std::string("Bomb_PLight") + GetName().data(), GetTransform(), GetUniqueId(),
|
||||
x184_particle2->GetLight(), reinterpret_cast<size_t>(x18c_), 1, 0.f);
|
||||
x184_particle2->GetLight(), reinterpret_cast<size_t>(x18c_particle2Obj), 1, 0.f);
|
||||
mgr.AddObject(gameLight);
|
||||
mgr.AddWeaponId(xec_ownerId, xf0_weaponType);
|
||||
CSfxManager::AddEmitter(SFXwpn_bomb_drop, GetTranslation(), {}, true, false, 0x7f, -1);
|
||||
|
|
|
@ -15,9 +15,9 @@ class CBomb : public CWeapon {
|
|||
std::unique_ptr<CElementGen> x180_particle1;
|
||||
std::unique_ptr<CElementGen> x184_particle2;
|
||||
TUniqueId x188_lightId = kInvalidUniqueId;
|
||||
const CGenDescription* x18c_;
|
||||
const CGenDescription* x18c_particle2Obj;
|
||||
bool x190_24_isNotDetonated : 1;
|
||||
bool x190_25_ : 1;
|
||||
bool x190_25_beingDragged : 1;
|
||||
bool x190_26_disableFuse : 1;
|
||||
|
||||
public:
|
||||
|
@ -35,6 +35,9 @@ public:
|
|||
std::optional<zeus::CAABox> GetTouchBounds() const;
|
||||
void SetVelocityWR(const zeus::CVector3f& vel) { x158_velocity = vel; }
|
||||
void SetConstantAccelerationWR(const zeus::CVector3f& acc) { x164_acceleration = acc; }
|
||||
void SetFuseDisabled(bool b) { x190_26_disableFuse = false; }
|
||||
void SetIsBeingDragged(bool b) { x190_25_beingDragged = b; }
|
||||
bool IsBeingDragged() const { return x190_25_beingDragged; }
|
||||
};
|
||||
|
||||
} // namespace urde
|
||||
|
|
|
@ -241,14 +241,14 @@ bool CEnergyProjectile::Explode(const zeus::CVector3f& pos, const zeus::CVector3
|
|||
EVulnerability vulnType = dVuln.GetVulnerability(x12c_curDamageInfo.GetWeaponMode(), false);
|
||||
if (vulnType == EVulnerability::Deflect) {
|
||||
deflect = true;
|
||||
EVulnerability deflectType = dVuln.GetDeflectionType(x12c_curDamageInfo.GetWeaponMode());
|
||||
EDeflectType deflectType = dVuln.GetDeflectionType(x12c_curDamageInfo.GetWeaponMode());
|
||||
switch (deflectType) {
|
||||
case EVulnerability::Weak:
|
||||
case EDeflectType::None:
|
||||
deflect = false;
|
||||
break;
|
||||
case EVulnerability::Deflect:
|
||||
case EVulnerability::Immune:
|
||||
if (deflectType != EVulnerability::Deflect ||
|
||||
case EDeflectType::Two:
|
||||
case EDeflectType::Three:
|
||||
if (deflectType != EDeflectType::Two ||
|
||||
(xf0_weaponType != EWeaponType::Missile &&
|
||||
(xe8_projectileAttribs & EProjectileAttrib::ComboShot) != EProjectileAttrib::ComboShot))
|
||||
if (xf8_filter.GetExcludeList().HasMaterial(EMaterialTypes::Player))
|
||||
|
|
|
@ -8,7 +8,7 @@ const CDamageVulnerability CDamageVulnerability::sNormalVulnerability(
|
|||
EVulnerability::Normal, EVulnerability::Normal, EVulnerability::Normal, EVulnerability::Normal,
|
||||
EVulnerability::Normal, EVulnerability::Normal, EVulnerability::Normal, EVulnerability::Normal,
|
||||
EVulnerability::Normal, EVulnerability::Normal, EVulnerability::Normal, EVulnerability::Normal,
|
||||
EVulnerability::Normal, EVulnerability::Normal, EVulnerability::Normal, EVulnerability::Weak);
|
||||
EVulnerability::Normal, EVulnerability::Normal, EVulnerability::Normal, EDeflectType::None);
|
||||
|
||||
const CDamageVulnerability CDamageVulnerability::sImmuneVulnerability(
|
||||
EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect,
|
||||
|
@ -16,7 +16,7 @@ const CDamageVulnerability CDamageVulnerability::sImmuneVulnerability(
|
|||
EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect,
|
||||
EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect,
|
||||
EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect,
|
||||
EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Weak);
|
||||
EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EDeflectType::None);
|
||||
/* LOL, thanks retro */
|
||||
const CDamageVulnerability CDamageVulnerability::sReflectVulnerability(
|
||||
EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect,
|
||||
|
@ -24,7 +24,7 @@ const CDamageVulnerability CDamageVulnerability::sReflectVulnerability(
|
|||
EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect,
|
||||
EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect,
|
||||
EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect,
|
||||
EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Weak);
|
||||
EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EDeflectType::None);
|
||||
|
||||
const CDamageVulnerability CDamageVulnerability::sPassThroughVulnerability(
|
||||
EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough,
|
||||
|
@ -32,7 +32,7 @@ const CDamageVulnerability CDamageVulnerability::sPassThroughVulnerability(
|
|||
EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough,
|
||||
EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough,
|
||||
EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough,
|
||||
EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::Weak);
|
||||
EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough, EDeflectType::None);
|
||||
|
||||
static inline bool is_not_immune(EVulnerability vuln) {
|
||||
return vuln != EVulnerability::Immune && vuln != EVulnerability::DirectImmune;
|
||||
|
@ -56,19 +56,19 @@ void CDamageVulnerability::ConstructNew(CInputStream& in, int propCount) {
|
|||
for (int i = 15; i < propCount; ++i)
|
||||
in.readUint32Big();
|
||||
|
||||
x5c_deflected = EVulnerability(in.readUint32Big());
|
||||
x5c_deflected = EDeflectType(in.readUint32Big());
|
||||
EVulnerability* vulns2 = &x3c_chargedPower;
|
||||
in.readUint32Big();
|
||||
for (int i = 0; i < 4; ++i)
|
||||
vulns2[i] = EVulnerability(in.readUint32Big());
|
||||
|
||||
x60_chargedDeflected = EVulnerability(in.readUint32Big());
|
||||
x60_chargedDeflected = EDeflectType(in.readUint32Big());
|
||||
EVulnerability* vulns3 = &x4c_superMissile;
|
||||
in.readUint32Big();
|
||||
for (int i = 0; i < 4; ++i)
|
||||
vulns3[i] = EVulnerability(in.readUint32Big());
|
||||
|
||||
x64_comboDeflected = EVulnerability(in.readUint32Big());
|
||||
x64_comboDeflected = EDeflectType(in.readUint32Big());
|
||||
}
|
||||
|
||||
CDamageVulnerability::CDamageVulnerability(CInputStream& in) {
|
||||
|
@ -79,9 +79,9 @@ CDamageVulnerability::CDamageVulnerability(CInputStream& in) {
|
|||
vulns[i] = EVulnerability(in.readUint32Big());
|
||||
|
||||
if (propCount == 15)
|
||||
x5c_deflected = EVulnerability::Weak;
|
||||
x5c_deflected = EDeflectType::None;
|
||||
else
|
||||
x5c_deflected = EVulnerability(in.readUint32Big());
|
||||
x5c_deflected = EDeflectType(in.readUint32Big());
|
||||
|
||||
x3c_chargedPower = x0_power;
|
||||
x4c_superMissile = x0_power;
|
||||
|
@ -95,13 +95,44 @@ CDamageVulnerability::CDamageVulnerability(CInputStream& in) {
|
|||
ConstructNew(in, propCount);
|
||||
}
|
||||
|
||||
CDamageVulnerability::CDamageVulnerability(EVulnerability power, EVulnerability ice, EVulnerability wave,
|
||||
EVulnerability plasma, EVulnerability bomb, EVulnerability powerBomb,
|
||||
EVulnerability missile, EVulnerability boostBall, EVulnerability phazon,
|
||||
EVulnerability enemyWp1, EVulnerability enemyWp2, EVulnerability enemyWp3,
|
||||
EVulnerability enemyWp4, EVulnerability v1, EVulnerability v2,
|
||||
EDeflectType deflectType)
|
||||
: x0_power(power)
|
||||
, x4_ice(ice)
|
||||
, x8_wave(wave)
|
||||
, xc_plasma(plasma)
|
||||
, x10_bomb(bomb)
|
||||
, x14_powerbomb(powerBomb)
|
||||
, x18_missile(missile)
|
||||
, x1c_boostBall(boostBall)
|
||||
, x20_phazon(phazon)
|
||||
, x24_enemyWp1(enemyWp1)
|
||||
, x28_enemyWp2Poison(enemyWp2)
|
||||
, x2c_enemyWp3Lava(enemyWp3)
|
||||
, x30_enemyWp4(enemyWp4)
|
||||
, x34_unk1(v1)
|
||||
, x38_unk2(v2)
|
||||
, x3c_chargedPower(x0_power)
|
||||
, x40_chargedIce(x4_ice)
|
||||
, x44_chargedWave(x8_wave)
|
||||
, x48_chargedPlasma(xc_plasma)
|
||||
, x4c_superMissile(x0_power)
|
||||
, x50_iceSpreader(x4_ice)
|
||||
, x54_wavebuster(x8_wave)
|
||||
, x58_flamethrower(xc_plasma)
|
||||
, x5c_deflected(deflectType) {}
|
||||
|
||||
CDamageVulnerability::CDamageVulnerability(
|
||||
EVulnerability power, EVulnerability ice, EVulnerability wave, EVulnerability plasma, EVulnerability bomb,
|
||||
EVulnerability powerBomb, EVulnerability missile, EVulnerability boostBall, EVulnerability phazon,
|
||||
EVulnerability enemyWp1, EVulnerability enemyWp2, EVulnerability enemyWp3, EVulnerability enemyWp4,
|
||||
EVulnerability v1, EVulnerability v2, EVulnerability chargedPower, EVulnerability chargedIce,
|
||||
EVulnerability chargedWave, EVulnerability chargedPlasma, EVulnerability superMissile, EVulnerability iceSpreader,
|
||||
EVulnerability waveBuster, EVulnerability flameThrower, EVulnerability deflected)
|
||||
EVulnerability waveBuster, EVulnerability flameThrower, EDeflectType deflected)
|
||||
: x0_power(power)
|
||||
, x4_ice(ice)
|
||||
, x8_wave(wave)
|
||||
|
@ -127,7 +158,7 @@ CDamageVulnerability::CDamageVulnerability(
|
|||
, x58_flamethrower(flameThrower)
|
||||
, x5c_deflected(deflected) {}
|
||||
|
||||
EVulnerability CDamageVulnerability::GetDeflectionType(const CWeaponMode& mode) const {
|
||||
EDeflectType CDamageVulnerability::GetDeflectionType(const CWeaponMode& mode) const {
|
||||
if (mode.IsCharged())
|
||||
return x60_chargedDeflected;
|
||||
if (mode.IsComboed())
|
||||
|
@ -205,9 +236,7 @@ bool CDamageVulnerability::WeaponHits(const CWeaponMode& mode, bool checkDirect)
|
|||
return true;
|
||||
if (chargedVuln && mode.IsCharged())
|
||||
return true;
|
||||
if (comboedVuln && mode.IsComboed())
|
||||
return true;
|
||||
return false;
|
||||
return comboedVuln && mode.IsComboed();
|
||||
}
|
||||
|
||||
EVulnerability CDamageVulnerability::GetVulnerability(const CWeaponMode& mode, bool ignoreDirect) const {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
namespace urde {
|
||||
|
||||
enum class EVulnerability { Weak, Normal, Deflect, Immune, PassThrough, DirectWeak, DirectNormal, DirectImmune };
|
||||
enum class EDeflectType { None, One, Two, Three, Four };
|
||||
|
||||
class CDamageVulnerability {
|
||||
EVulnerability x0_power;
|
||||
|
@ -34,9 +35,12 @@ class CDamageVulnerability {
|
|||
EVulnerability x54_wavebuster;
|
||||
EVulnerability x58_flamethrower;
|
||||
|
||||
EVulnerability x5c_deflected;
|
||||
EVulnerability x60_chargedDeflected;
|
||||
EVulnerability x64_comboDeflected;
|
||||
EDeflectType x5c_deflected;
|
||||
/* The following two values are hard coded to bizarre values on purpose to more closely reflect the behavior seen
|
||||
* in-game.
|
||||
*/
|
||||
EDeflectType x60_chargedDeflected = EDeflectType(6);
|
||||
EDeflectType x64_comboDeflected = EDeflectType(0x3e666666);
|
||||
|
||||
void ConstructNew(CInputStream& in, int propCount);
|
||||
|
||||
|
@ -47,15 +51,19 @@ class CDamageVulnerability {
|
|||
|
||||
public:
|
||||
CDamageVulnerability(CInputStream& in);
|
||||
CDamageVulnerability(EVulnerability power, EVulnerability ice, EVulnerability wave, EVulnerability plasma,
|
||||
EVulnerability bomb, EVulnerability powerBomb, EVulnerability missile, EVulnerability boostBall,
|
||||
EVulnerability phazon, EVulnerability enemyWp1, EVulnerability wnemyWp2, EVulnerability enemyWp3,
|
||||
EVulnerability enemyWp4, EVulnerability v1, EVulnerability v2, EDeflectType deflectType);
|
||||
CDamageVulnerability(EVulnerability power, EVulnerability ice, EVulnerability wave, EVulnerability plasma,
|
||||
EVulnerability bomb, EVulnerability powerBomb, EVulnerability missile, EVulnerability boostBall,
|
||||
EVulnerability phazon, EVulnerability enemyWp1, EVulnerability enemyWp2, EVulnerability enemyWp3,
|
||||
EVulnerability enemyWp4, EVulnerability v1, EVulnerability v2, EVulnerability chargedPower,
|
||||
EVulnerability chargedIce, EVulnerability chargedWave, EVulnerability chargedPlasma,
|
||||
EVulnerability superMissile, EVulnerability iceSpreader, EVulnerability waveBuster,
|
||||
EVulnerability flameThrower, EVulnerability deflected);
|
||||
EVulnerability flameThrower, EDeflectType deflected);
|
||||
|
||||
EVulnerability GetDeflectionType(const CWeaponMode& mode) const;
|
||||
EDeflectType GetDeflectionType(const CWeaponMode& mode) const;
|
||||
|
||||
bool WeaponHurts(const CWeaponMode&, bool ignoreDirect) const;
|
||||
bool WeaponHits(const CWeaponMode& mode, bool checkDirect) const;
|
||||
|
|
|
@ -346,7 +346,7 @@ public:
|
|||
virtual CDamageInfo GetContactDamage() const { return x404_contactDamage; }
|
||||
virtual u8 GetModelAlphau8(const CStateManager&) const { return u8(x42c_color.a() * 255); }
|
||||
virtual bool IsOnGround() const { return x328_27_onGround; }
|
||||
virtual float GetGravityConstant() const { return 24.525002f; }
|
||||
virtual float GetGravityConstant() const { return CPhysicsActor::GravityConstant(); }
|
||||
virtual CProjectileInfo* GetProjectileInfo() { return nullptr; }
|
||||
virtual void PhazeOut(CStateManager&);
|
||||
virtual const std::optional<TLockedToken<CGenDescription>>& GetDeathExplosionParticle() const {
|
||||
|
|
|
@ -47,7 +47,7 @@ float CPhysicsActor::GetStepUpHeight() const { return x23c_stepUpHeight; }
|
|||
|
||||
float CPhysicsActor::GetStepDownHeight() const { return x240_stepDownHeight; }
|
||||
|
||||
float CPhysicsActor::GetWeight() const { return 24.525002f * xe8_mass; }
|
||||
float CPhysicsActor::GetWeight() const { return CPhysicsActor::GravityConstant() * xe8_mass; }
|
||||
|
||||
void CPhysicsActor::SetPrimitiveOffset(const zeus::CVector2f& offset) { x1e8_primitiveOffset = offset; }
|
||||
|
||||
|
|
|
@ -202,5 +202,6 @@ public:
|
|||
void ApplyTorqueWR(const zeus::CVector3f& torque);
|
||||
|
||||
void UseCollisionImpulses();
|
||||
static constexpr float GravityConstant() { return 9.81f * 2.5f; } /* 9.81 m/s ^ 2 is normal acceleration under earth gravity, Tallon 4 is 2.5 times that */
|
||||
};
|
||||
} // namespace urde
|
||||
|
|
|
@ -174,8 +174,8 @@ EWeaponCollisionResponseTypes CScriptActor::GetCollisionResponseType(const zeus:
|
|||
EProjectileAttrib w) const {
|
||||
const CDamageVulnerability* dVuln = GetDamageVulnerability();
|
||||
if (dVuln->GetVulnerability(wMode, false) == EVulnerability::Deflect) {
|
||||
EVulnerability phazonVuln = dVuln->GetDeflectionType(wMode);
|
||||
if (phazonVuln < EVulnerability::PassThrough && phazonVuln >= EVulnerability::Normal)
|
||||
EDeflectType deflectType = dVuln->GetDeflectionType(wMode);
|
||||
if (deflectType < EDeflectType::Four && deflectType >= EDeflectType::One)
|
||||
return EWeaponCollisionResponseTypes::Unknown15;
|
||||
}
|
||||
return CActor::GetCollisionResponseType(v1, v2, wMode, w);
|
||||
|
|
|
@ -53,7 +53,7 @@ CScriptDebris::CScriptDebris(TUniqueId uid, std::string_view name, const CEntity
|
|||
x2d4_particleGens[0]->SetGlobalScale(particleScale);
|
||||
}
|
||||
|
||||
x150_momentum = zeus::CVector3f(0.f, 0.f, -24.525f * xe8_mass);
|
||||
x150_momentum = zeus::CVector3f(0.f, 0.f, -CPhysicsActor::GravityConstant() * xe8_mass);
|
||||
|
||||
if (x90_actorLights)
|
||||
x90_actorLights->SetAmbienceGenerated(true);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "GameGlobalObjects.hpp"
|
||||
#include "CStateManager.hpp"
|
||||
#include "CSimplePool.hpp"
|
||||
#include "World/CPhysicsActor.hpp"
|
||||
#include "TCastTo.hpp"
|
||||
|
||||
namespace urde {
|
||||
|
@ -490,7 +491,7 @@ void CWallCrawlerSwarm::UpdateBoid(const CAreaCollisionCache& ccache, CStateMana
|
|||
f28 += f25;
|
||||
}
|
||||
if (!found) {
|
||||
boid.x30_velocity += zeus::CVector3f(0.f, 0.f, -(x558_flavor == EFlavor::Scarab ? 3.f * 24.525f : 24.525f)) * dt;
|
||||
boid.x30_velocity += zeus::CVector3f(0.f, 0.f, -(x558_flavor == EFlavor::Scarab ? 3.f * CPhysicsActor::GravityConstant() : CPhysicsActor::GravityConstant())) * dt;
|
||||
if (boid.x7c_remainingLaunchNotOnSurfaceFrames)
|
||||
boid.x7c_remainingLaunchNotOnSurfaceFrames -= 1;
|
||||
}
|
||||
|
@ -561,7 +562,7 @@ void CWallCrawlerSwarm::UpdateBoid(const CAreaCollisionCache& ccache, CStateMana
|
|||
|
||||
void CWallCrawlerSwarm::LaunchBoid(CBoid& boid, const zeus::CVector3f& dir) {
|
||||
zeus::CVector3f pos = boid.GetTranslation();
|
||||
static float skAttackTime = std::sqrt(2.5f / 24.525f) * 2.f;
|
||||
static float skAttackTime = std::sqrt(2.5f / CPhysicsActor::GravityConstant()) * 2.f;
|
||||
static float skAttackVelocity = 15.f / skAttackTime;
|
||||
zeus::CVector3f deltaFlat = dir - pos;
|
||||
float deltaZ = deltaFlat.z();
|
||||
|
@ -578,14 +579,14 @@ void CWallCrawlerSwarm::LaunchBoid(CBoid& boid, const zeus::CVector3f& dir) {
|
|||
bool r29 = deltaZ < 0.f;
|
||||
float _12c, _130;
|
||||
float f25 = 0.f;
|
||||
if (CSteeringBehaviors::SolveQuadratic(-24.525f, vec.z(), -deltaZ, _12c, _130))
|
||||
if (CSteeringBehaviors::SolveQuadratic(-CPhysicsActor::GravityConstant(), vec.z(), -deltaZ, _12c, _130))
|
||||
f25 = r29 ? _130 : _12c;
|
||||
if (!r29)
|
||||
f25 += deltaMag / dot;
|
||||
if (f25 < 10.f) {
|
||||
vec.x() = deltaMag / f25 * deltaFlat.x() * 0.6f;
|
||||
vec.y() = deltaMag / f25 * deltaFlat.y() * 0.6f;
|
||||
vec.z() = deltaZ / f25 - 0.5f * -24.525f * f25;
|
||||
vec.z() = deltaZ / f25 - 0.5f * -CPhysicsActor::GravityConstant() * f25;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue