mirror of https://github.com/AxioDL/metaforce.git
CElitePirate: Nearly complete implementation
This commit is contained in:
parent
4f7e0a85a3
commit
4ada5a00cb
|
@ -68,7 +68,7 @@ enum class EFallState { Invalid = -1, Zero, One , Two};
|
|||
|
||||
enum class EReactionType { Invalid = -1, Zero, One, Two, Three };
|
||||
|
||||
enum class EAdditiveReactionType { Invalid = -1, Electrocution, One, Two, IceBreakout };
|
||||
enum class EAdditiveReactionType { Invalid = -1, Electrocution, One, Two, IceBreakout, Four, Five, Six, Seven };
|
||||
|
||||
enum class EJumpType { Normal, One, Ambush };
|
||||
|
||||
|
@ -96,7 +96,7 @@ enum class ELoopState { Invalid = -1, Begin, Loop, End };
|
|||
|
||||
enum class ELoopAttackType { Invalid = -1 };
|
||||
|
||||
enum class EGenerateType { Invalid = -1, Zero, One, Two, Three, Four };
|
||||
enum class EGenerateType { Invalid = -1, Zero, One, Two, Three, Four, Five };
|
||||
|
||||
enum class ESlideType { Invalid = -1, Zero = 0 };
|
||||
|
||||
|
|
|
@ -41,8 +41,8 @@ static constexpr std::array<SSphereJointInfo, 7> skSphereJointList{{
|
|||
} // namespace
|
||||
|
||||
CElitePirateData::CElitePirateData(CInputStream& in, u32 propCount)
|
||||
: x0_(in.readFloatBig())
|
||||
, x4_(in.readFloatBig())
|
||||
: x0_tauntInterval(in.readFloatBig())
|
||||
, x4_tauntVariance(in.readFloatBig())
|
||||
, x8_(in.readFloatBig())
|
||||
, xc_(in.readFloatBig())
|
||||
, x10_(in.readFloatBig())
|
||||
|
@ -57,13 +57,13 @@ CElitePirateData::CElitePirateData(CInputStream& in, u32 propCount)
|
|||
, xa0_(CSfxManager::TranslateSFXID(in.readUint32Big()))
|
||||
, xa4_(in)
|
||||
, xa8_(in)
|
||||
, xc4_(in.readFloatBig())
|
||||
, xc4_launcherHp(in.readFloatBig())
|
||||
, xc8_(in)
|
||||
, xcc_(in)
|
||||
, xd0_(in)
|
||||
, xd4_(in)
|
||||
, xd8_(in)
|
||||
, xe0_(in.readFloatBig(), in.readFloatBig(), zeus::degToRad(in.readFloatBig()), zeus::degToRad(in.readFloatBig()))
|
||||
, xe0_trajectoryInfo(in)
|
||||
, xf0_(in)
|
||||
, xf4_(CSfxManager::TranslateSFXID(in.readUint32Big()))
|
||||
, xf6_(CSfxManager::TranslateSFXID(in.readUint32Big()))
|
||||
|
@ -72,15 +72,15 @@ CElitePirateData::CElitePirateData(CInputStream& in, u32 propCount)
|
|||
, x118_(in)
|
||||
, x11c_(CSfxManager::TranslateSFXID(in.readUint32Big()))
|
||||
, x11e_(in.readBool())
|
||||
, x11f_(propCount < 24 ? true : in.readBool()) {}
|
||||
, x11f_(propCount < 42 ? true : in.readBool()) {}
|
||||
|
||||
CElitePirate::CElitePirate(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf,
|
||||
CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& actParms,
|
||||
const CElitePirateData& eliteData)
|
||||
const CElitePirateData& data)
|
||||
: CPatterned(ECharacter::ElitePirate, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo,
|
||||
EMovementType::Ground, EColliderType::One, EBodyType::BiPedal, actParms, EKnockBackVariant::Large)
|
||||
, x56c_vulnerability(pInfo.GetDamageVulnerability())
|
||||
, x5d8_data(eliteData)
|
||||
, x5d8_data(data)
|
||||
, x6f8_boneTracking(*GetModelData()->GetAnimationData(), "Head_1", zeus::degToRad(80.f), zeus::degToRad(180.f),
|
||||
EBoneTrackingFlags::None)
|
||||
, x738_(GetBoundingBox(), GetMaterialList())
|
||||
|
@ -96,7 +96,7 @@ CElitePirate::CElitePirate(TUniqueId uid, std::string_view name, const CEntityIn
|
|||
, x988_31_(false)
|
||||
, x989_24_(false) {
|
||||
if (x5d8_data.GetX20().IsValid()) {
|
||||
x760_ = g_SimplePool->GetObj({SBIG('PART'), x5d8_data.GetX20()});
|
||||
x760_energyAbsorbDesc = g_SimplePool->GetObj({SBIG('PART'), x5d8_data.GetX20()});
|
||||
}
|
||||
|
||||
x460_knockBackController.SetEnableFreeze(false);
|
||||
|
@ -109,7 +109,26 @@ CElitePirate::CElitePirate(TUniqueId uid, std::string_view name, const CEntityIn
|
|||
|
||||
void CElitePirate::Accept(IVisitor& visitor) { visitor.Visit(this); }
|
||||
|
||||
void CElitePirate::Think(float dt, CStateManager& mgr) { CPatterned::Think(dt, mgr); }
|
||||
void CElitePirate::Think(float dt, CStateManager& mgr) {
|
||||
if (GetActive()) {
|
||||
CPatterned::Think(dt, mgr);
|
||||
x6f8_boneTracking.Update(dt);
|
||||
if (sub_802273a8()) {
|
||||
x730_collisionActorMgr2->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace);
|
||||
}
|
||||
x5d4_collisionActorMgr1->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace);
|
||||
if (sub_80229208() && x5d8_data.x11f_) {
|
||||
x3b4_speed = 2.f * x7a0_;
|
||||
} else {
|
||||
x3b4_speed = x7a0_;
|
||||
}
|
||||
sub_80228e50(dt);
|
||||
sub_80228798();
|
||||
sub_802289dc(mgr, x772_launcherId, "grenadeLauncher_LCTR"sv);
|
||||
sub_80228e84(mgr);
|
||||
x328_31_ = sub_80229208();
|
||||
}
|
||||
}
|
||||
|
||||
void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) {
|
||||
bool shouldPass = true;
|
||||
|
@ -149,7 +168,7 @@ void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSta
|
|||
}
|
||||
const TUniqueId& touchedUid = actor->GetLastTouchedObject();
|
||||
if (touchedUid != GetUniqueId()) {
|
||||
if (TCastToPtr<CGameProjectile> projectile = mgr.ObjectById(touchedUid)) {
|
||||
if (TCastToPtr<CGameProjectile>(mgr.ObjectById(touchedUid))) {
|
||||
sub_8022759c(true, mgr);
|
||||
}
|
||||
break;
|
||||
|
@ -207,8 +226,8 @@ void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSta
|
|||
KnockBack(projectile->GetTranslation() - projectile->GetPreviousPos(), mgr, damageInfo,
|
||||
EKnockBackType::Radius, false, damageInfo.GetKnockBackPower());
|
||||
CPatterned::AcceptScriptMsg(msg, uid, mgr);
|
||||
} else if (uid == x79c_ && x760_->IsLoaded()) {
|
||||
sub_802281d8(mgr, projectile->GetTransform());
|
||||
} else if (uid == x79c_ && x760_energyAbsorbDesc->IsLoaded()) {
|
||||
CreateEnergyAbsorb(mgr, projectile->GetTransform());
|
||||
}
|
||||
sub_8022759c(true, mgr);
|
||||
}
|
||||
|
@ -216,14 +235,13 @@ void CElitePirate::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSta
|
|||
x450_bodyController->GetCommandMgr().DeliverCmd(
|
||||
CBCKnockBackCmd(GetTransform().frontVector(), pas::ESeverity::Eight));
|
||||
} else {
|
||||
sub_80227464(mgr, uid);
|
||||
ApplyDamageToHead(mgr, uid);
|
||||
}
|
||||
break;
|
||||
case EScriptObjectMessage::InvulnDamage: {
|
||||
sub_8022759c(true, mgr);
|
||||
TCastToPtr<CCollisionActor> actor = mgr.ObjectById(uid);
|
||||
if (!actor) {
|
||||
sub_80227464(mgr, uid);
|
||||
if (!TCastToPtr<CCollisionActor>(mgr.ObjectById(uid))) {
|
||||
ApplyDamageToHead(mgr, uid);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -269,7 +287,7 @@ zeus::CVector3f CElitePirate::GetOrbitPosition(const CStateManager& mgr) const {
|
|||
return GetLctrTransform("lockon_target_LCTR").origin;
|
||||
}
|
||||
|
||||
zeus::CVector3f CElitePirate::GetAimPosition(const CStateManager& mgr, float dt) const {
|
||||
zeus::CVector3f CElitePirate::GetAimPosition(const CStateManager& mgr, float) const {
|
||||
std::shared_ptr<CPlayerState> playerState = mgr.GetPlayerState();
|
||||
if (x5d4_collisionActorMgr1->GetActive() && playerState->IsFiringComboBeam() &&
|
||||
playerState->GetCurrentBeam() == CPlayerState::EBeamId::Wave) {
|
||||
|
@ -370,28 +388,28 @@ void CElitePirate::PathFind(CStateManager& mgr, EStateMsg msg, float dt) {
|
|||
x6f8_boneTracking.SetActive(true);
|
||||
sub_80228634(mgr);
|
||||
CPatterned::PathFind(mgr, msg, dt);
|
||||
x7bc_ = x5d8_data.x4_ * mgr.GetActiveRandom()->Float() + x5d8_data.x0_;
|
||||
x7bc_tauntTimer = x5d8_data.x4_tauntVariance * mgr.GetActiveRandom()->Float() + x5d8_data.x0_tauntInterval;
|
||||
if (TooClose(mgr, 0.f)) {
|
||||
x450_bodyController->GetCommandMgr().ClearLocomotionCmds();
|
||||
}
|
||||
} else if (msg == EStateMsg::Update) {
|
||||
if (x7bc_ > 0.f) {
|
||||
x7bc_ -= dt;
|
||||
if (x7bc_tauntTimer > 0.f) {
|
||||
x7bc_tauntTimer -= dt;
|
||||
}
|
||||
if (!TooClose(mgr, 0.f) && !PathShagged(mgr, 0.f)) {
|
||||
CPatterned::PathFind(mgr, msg, dt);
|
||||
} else {
|
||||
if (PathShagged(mgr, 0.f)) {
|
||||
const zeus::CVector3f& move = x8c0_.sub_802a07f0(GetTranslation(), GetTransform().frontVector());
|
||||
const zeus::CVector3f& move = x8c0_.GetValue(GetTranslation(), GetTransform().frontVector());
|
||||
if (move != zeus::skZero3f) {
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(move, zeus::skZero3f, 1.f));
|
||||
}
|
||||
} else if (ShouldTurn(mgr, 0.f)) {
|
||||
const zeus::CVector3f& aim =
|
||||
mgr.GetPlayer().GetAimPosition(mgr, 0.5f * GetModelData()->GetAnimationData()->GetSpeedScale());
|
||||
const zeus::CVector3f& move = aim - GetTranslation();
|
||||
if (move.canBeNormalized()) {
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(zeus::skZero3f, move.normalized(), 1.f));
|
||||
const zeus::CVector3f& face = aim - GetTranslation();
|
||||
if (face.canBeNormalized()) {
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(zeus::skZero3f, face.normalized(), 1.f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -400,9 +418,32 @@ void CElitePirate::PathFind(CStateManager& mgr, EStateMsg msg, float dt) {
|
|||
}
|
||||
}
|
||||
|
||||
void CElitePirate::TargetPatrol(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::TargetPatrol(mgr, msg, dt); }
|
||||
void CElitePirate::TargetPatrol(CStateManager& mgr, EStateMsg msg, float dt) {
|
||||
if (msg == EStateMsg::Activate) {
|
||||
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed);
|
||||
if (HasPatrolPath(mgr, 0.f)) {
|
||||
CPatterned::Patrol(mgr, msg, dt);
|
||||
UpdateDest(mgr);
|
||||
} else {
|
||||
SetDestPos(x3a0_latestLeashPosition);
|
||||
}
|
||||
x8b4_ = x2e0_destPos;
|
||||
if (GetSearchPath() != nullptr) {
|
||||
CPatterned::PathFind(mgr, msg, dt);
|
||||
}
|
||||
} else if (msg == EStateMsg::Update) {
|
||||
if (PathShagged(mgr, 0.f)) {
|
||||
const zeus::CVector3f& move = x45c_steeringBehaviors.Arrival(*this, x8b4_, 25.f);
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(move, zeus::skZero3f, 1.f));
|
||||
} else {
|
||||
CPatterned::PathFind(mgr, msg, dt);
|
||||
}
|
||||
} else if (msg == EStateMsg::Deactivate) {
|
||||
x988_28_alert = false;
|
||||
}
|
||||
}
|
||||
|
||||
void CElitePirate::Halt(CStateManager& mgr, EStateMsg msg, float dt) {
|
||||
void CElitePirate::Halt(CStateManager& mgr, EStateMsg msg, float) {
|
||||
if (msg == EStateMsg::Activate) {
|
||||
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk);
|
||||
x989_24_ = false;
|
||||
|
@ -429,15 +470,15 @@ void CElitePirate::Run(CStateManager& mgr, EStateMsg msg, float dt) {
|
|||
CPatterned::PathFind(mgr, msg, dt);
|
||||
} else if (msg == EStateMsg::Update) {
|
||||
if (PathShagged(mgr, 0.f)) {
|
||||
auto move = x8c0_.sub_802a07f0(GetTranslation(), GetTransform().frontVector());
|
||||
auto move = x8c0_.GetValue(GetTranslation(), GetTransform().frontVector());
|
||||
if (move != zeus::skZero3f) {
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(move, zeus::skZero3f, 1.f));
|
||||
} else if (ShouldTurn(mgr, 0.f)) {
|
||||
const zeus::CVector3f& aim =
|
||||
mgr.GetPlayer().GetAimPosition(mgr, 0.5f * GetModelData()->GetAnimationData()->GetSpeedScale());
|
||||
move = aim - GetTranslation();
|
||||
if (move.canBeNormalized()) {
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(zeus::skZero3f, move.normalized(), 1.f));
|
||||
auto face = aim - GetTranslation();
|
||||
if (face.canBeNormalized()) {
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(zeus::skZero3f, face.normalized(), 1.f));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -450,65 +491,104 @@ void CElitePirate::Run(CStateManager& mgr, EStateMsg msg, float dt) {
|
|||
}
|
||||
}
|
||||
|
||||
void CElitePirate::Generate(CStateManager& mgr, EStateMsg msg, float dt) {
|
||||
switch (msg) {
|
||||
case EStateMsg::Activate:
|
||||
x568_ = 1;
|
||||
break;
|
||||
case EStateMsg::Update:
|
||||
switch (x568_) {
|
||||
case 0:
|
||||
void CElitePirate::Generate(CStateManager& mgr, EStateMsg msg, float) {
|
||||
if (msg == EStateMsg::Activate) {
|
||||
x568_ = EState::One;
|
||||
} else if (msg == EStateMsg::Update) {
|
||||
if (x568_ == EState::Zero) {
|
||||
if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::Generate) {
|
||||
x568_ = 2;
|
||||
x568_ = EState::Two;
|
||||
} else {
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCGenerateCmd(pas::EGenerateType::Zero));
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
} else if (x568_ == EState::One) {
|
||||
if (ShouldTurn(mgr, 0.f)) {
|
||||
const auto& playerPos = mgr.GetPlayer().GetTranslation();
|
||||
if (playerPos.canBeNormalized()) {
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(
|
||||
CBCLocomotionCmd(zeus::skZero3f, playerPos.normalized(), 1.f));
|
||||
const auto& face = mgr.GetPlayer().GetTranslation() - GetTranslation();
|
||||
if (face.canBeNormalized()) {
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(zeus::skZero3f, face.normalized(), 1.f));
|
||||
}
|
||||
} else {
|
||||
x568_ = 0;
|
||||
x568_ = EState::Zero;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (x450_bodyController->GetCurrentStateId() != pas::EAnimationState::Generate) {
|
||||
x568_ = 3;
|
||||
} else if (x568_ == EState::Two && x450_bodyController->GetCurrentStateId() != pas::EAnimationState::Generate) {
|
||||
x568_ = EState::Over;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case EStateMsg::Deactivate:
|
||||
} else if (msg == EStateMsg::Deactivate) {
|
||||
sub_8022759c(false, mgr);
|
||||
sub_802289b0(mgr, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CElitePirate::Attack(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Attack(mgr, msg, dt); }
|
||||
void CElitePirate::Attack(CStateManager& mgr, EStateMsg msg, float) {
|
||||
if (msg == EStateMsg::Activate) {
|
||||
x568_ = EState::Zero;
|
||||
ExtendTouchBounds(mgr, x774_collisionRJointIds, zeus::CVector3f(2.f));
|
||||
if (x64_modelData->GetNumMaterialSets() > 1) {
|
||||
x7cc_ = 1;
|
||||
}
|
||||
} else if (msg == EStateMsg::Update) {
|
||||
if (x568_ == EState::Zero) {
|
||||
if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::MeleeAttack) {
|
||||
x568_ = EState::One;
|
||||
x988_25_ = true;
|
||||
x7c8_currAnimId = x450_bodyController->GetCurrentAnimId();
|
||||
} else {
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCMeleeAttackCmd(pas::ESeverity::One));
|
||||
}
|
||||
} else if (x568_ == EState::One) {
|
||||
if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::MeleeAttack) {
|
||||
if (x7c8_currAnimId == x450_bodyController->GetCurrentAnimId()) {
|
||||
x450_bodyController->GetCommandMgr().DeliverTargetVector(mgr.GetPlayer().GetTranslation() - GetTranslation());
|
||||
if (ShouldAttack(mgr, 0.f)) {
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCMeleeAttackCmd(pas::ESeverity::Two));
|
||||
}
|
||||
} else {
|
||||
x568_ = EState::Two;
|
||||
x988_25_ = false;
|
||||
x988_26_ = true;
|
||||
ExtendTouchBounds(mgr, x774_collisionRJointIds, zeus::skZero3f);
|
||||
ExtendTouchBounds(mgr, x788_collisionLJointIds, zeus::CVector3f(2.f));
|
||||
}
|
||||
} else {
|
||||
x568_ = EState::Over;
|
||||
}
|
||||
} else if (x568_ == EState::Two) {
|
||||
if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::MeleeAttack) {
|
||||
x450_bodyController->GetCommandMgr().DeliverTargetVector(mgr.GetPlayer().GetTranslation() - GetTranslation());
|
||||
} else {
|
||||
x568_ = EState::Over;
|
||||
}
|
||||
}
|
||||
} else if (msg == EStateMsg::Deactivate) {
|
||||
sub_802285c4(mgr);
|
||||
x988_24_ = false;
|
||||
x988_26_ = false;
|
||||
x988_25_ = false;
|
||||
x7c8_currAnimId = -1;
|
||||
ExtendTouchBounds(mgr, x774_collisionRJointIds, zeus::skZero3f);
|
||||
ExtendTouchBounds(mgr, x788_collisionLJointIds, zeus::skZero3f);
|
||||
x7cc_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CElitePirate::Taunt(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Taunt(mgr, msg, dt); }
|
||||
|
||||
void CElitePirate::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float dt) {
|
||||
void CElitePirate::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float) {
|
||||
if (msg == EStateMsg::Activate) {
|
||||
x568_ = 0;
|
||||
x568_ = EState::Zero;
|
||||
} else if (msg == EStateMsg::Update) {
|
||||
const zeus::CVector3f& playerPos = mgr.GetPlayer().GetTranslation();
|
||||
if (x568_ == 0) {
|
||||
if (x568_ == EState::Zero) {
|
||||
if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::ProjectileAttack) {
|
||||
x568_ = 2;
|
||||
x568_ = EState::Two;
|
||||
} else {
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCProjectileAttackCmd(pas::ESeverity::One, playerPos, false));
|
||||
}
|
||||
} else if (x568_ == 2) {
|
||||
} else if (x568_ == EState::Two) {
|
||||
if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::ProjectileAttack) {
|
||||
x450_bodyController->GetCommandMgr().DeliverTargetVector(playerPos - GetTranslation());
|
||||
} else {
|
||||
x568_ = 3;
|
||||
x568_ = EState::Over;
|
||||
}
|
||||
}
|
||||
} else if (msg == EStateMsg::Deactivate) {
|
||||
|
@ -518,32 +598,105 @@ void CElitePirate::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float dt)
|
|||
|
||||
void CElitePirate::SpecialAttack(CStateManager& mgr, EStateMsg msg, float dt) { CAi::SpecialAttack(mgr, msg, dt); }
|
||||
|
||||
void CElitePirate::CallForBackup(CStateManager& mgr, EStateMsg msg, float dt) { CAi::CallForBackup(mgr, msg, dt); }
|
||||
|
||||
bool CElitePirate::TooClose(CStateManager& mgr, float arg) { return CPatterned::TooClose(mgr, arg); }
|
||||
|
||||
bool CElitePirate::InDetectionRange(CStateManager& mgr, float arg) {
|
||||
if (x988_28_alert) {
|
||||
return true;
|
||||
void CElitePirate::CallForBackup(CStateManager& mgr, EStateMsg msg, float) {
|
||||
if (msg == EStateMsg::Activate) {
|
||||
x568_ = EState::Zero;
|
||||
x988_30_ = true;
|
||||
sub_8022759c(false, mgr);
|
||||
} else if (msg == EStateMsg::Update) {
|
||||
if (x568_ == EState::Zero) {
|
||||
if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::Generate) {
|
||||
x568_ = EState::Two;
|
||||
} else {
|
||||
return CPatterned::InDetectionRange(mgr, arg);
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCGenerateCmd(pas::EGenerateType::Five, zeus::skZero3f));
|
||||
}
|
||||
} else if (x568_ == EState::Two) {
|
||||
if (x450_bodyController->GetCurrentStateId() != pas::EAnimationState::Generate) {
|
||||
x568_ = EState::Over;
|
||||
}
|
||||
}
|
||||
} else if (msg == EStateMsg::Deactivate) {
|
||||
SendScriptMsgs(EScriptObjectState::Zero, mgr, EScriptObjectMessage::None);
|
||||
}
|
||||
}
|
||||
|
||||
bool CElitePirate::SpotPlayer(CStateManager& mgr, float arg) { return CPatterned::SpotPlayer(mgr, arg); }
|
||||
void CElitePirate::Cover(CStateManager& mgr, EStateMsg msg, float dt) {
|
||||
if (msg == EStateMsg::Activate) {
|
||||
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Crouch);
|
||||
if (sub_802273a8()) {
|
||||
if (TCastToPtr<CCollisionActor> actor = mgr.ObjectById(x770_collisionHeadId)) {
|
||||
actor->SetDamageVulnerability(CDamageVulnerability::ImmuneVulnerabilty());
|
||||
}
|
||||
}
|
||||
x5d4_collisionActorMgr1->SetActive(mgr, true);
|
||||
x6f8_boneTracking.SetTarget(mgr.GetPlayer().GetUniqueId());
|
||||
x6f8_boneTracking.SetActive(true);
|
||||
sub_80228634(mgr);
|
||||
CPatterned::PathFind(mgr, msg, dt);
|
||||
if (TooClose(mgr, 0.f)) {
|
||||
x450_bodyController->GetCommandMgr().ClearLocomotionCmds();
|
||||
}
|
||||
} else if (msg == EStateMsg::Update) {
|
||||
if (x988_27_) {
|
||||
x7c0_ -= dt;
|
||||
if (x7c0_ <= 0.f) {
|
||||
x988_27_ = false;
|
||||
}
|
||||
}
|
||||
x7a8_ = PathShagged(mgr, 0.f) ? x7a8_ + dt : 0.f;
|
||||
if (!TooClose(mgr, 0.f) && !PathShagged(mgr, 0.f)) {
|
||||
CPatterned::PathFind(mgr, msg, dt);
|
||||
} else if (PathShagged(mgr, 0.f)) {
|
||||
const zeus::CVector3f& move = x8c0_.GetValue(GetTranslation(), GetTransform().frontVector());
|
||||
if (move != zeus::skZero3f) {
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(move, zeus::skZero3f, 1.f));
|
||||
}
|
||||
} else if (ShouldTurn(mgr, 0.f)) {
|
||||
const zeus::CVector3f& aim =
|
||||
mgr.GetPlayer().GetAimPosition(mgr, 0.5f * GetModelData()->GetAnimationData()->GetSpeedScale());
|
||||
const zeus::CVector3f& face = aim - GetTranslation();
|
||||
if (face.canBeNormalized()) {
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(zeus::skZero3f, face.normalized(), 1.f));
|
||||
}
|
||||
}
|
||||
sub_80227a90(mgr);
|
||||
sub_802277e0(mgr, dt);
|
||||
} else if (msg == EStateMsg::Deactivate) {
|
||||
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed);
|
||||
x6f8_boneTracking.SetActive(false);
|
||||
if (sub_802273a8()) {
|
||||
if (TCastToPtr<CCollisionActor> actor = mgr.ObjectById(x770_collisionHeadId)) {
|
||||
actor->SetDamageVulnerability(x56c_vulnerability);
|
||||
}
|
||||
}
|
||||
x5d4_collisionActorMgr1->SetActive(mgr, false);
|
||||
}
|
||||
}
|
||||
|
||||
bool CElitePirate::AnimOver(CStateManager& mgr, float arg) { return x568_ == 3; }
|
||||
bool CElitePirate::TooClose(CStateManager& mgr, float) {
|
||||
return x2fc_minAttackRange * x2fc_minAttackRange > (GetTranslation() - mgr.GetPlayer().GetTranslation()).magSquared();
|
||||
}
|
||||
|
||||
bool CElitePirate::ShouldAttack(CStateManager& mgr, float arg) {
|
||||
bool CElitePirate::InDetectionRange(CStateManager& mgr, float arg) {
|
||||
return x988_28_alert ? true : CPatterned::InDetectionRange(mgr, arg);
|
||||
}
|
||||
|
||||
bool CElitePirate::SpotPlayer(CStateManager& mgr, float arg) {
|
||||
return x988_28_alert ? true : CPatterned::SpotPlayer(mgr, arg);
|
||||
}
|
||||
|
||||
bool CElitePirate::AnimOver(CStateManager& mgr, float) { return x568_ == EState::Over; }
|
||||
|
||||
bool CElitePirate::ShouldAttack(CStateManager& mgr, float) {
|
||||
if ((mgr.GetPlayer().GetTranslation() - GetTranslation()).magSquared() > x2fc_minAttackRange * x2fc_minAttackRange) {
|
||||
return false;
|
||||
}
|
||||
return !ShouldTurn(mgr, 0.f);
|
||||
}
|
||||
|
||||
bool CElitePirate::InPosition(CStateManager& mgr, float arg) { return (x8b4_ - GetTranslation()).magSquared() < 25.f; }
|
||||
bool CElitePirate::InPosition(CStateManager& mgr, float) { return (x8b4_ - GetTranslation()).magSquared() < 25.f; }
|
||||
|
||||
bool CElitePirate::ShouldTurn(CStateManager& mgr, float arg) {
|
||||
bool CElitePirate::ShouldTurn(CStateManager& mgr, float) {
|
||||
return zeus::CVector2f::getAngleDiff((mgr.GetPlayer().GetTranslation() - GetTranslation()).toVec2f(),
|
||||
GetTransform().frontVector().toVec2f()) > zeus::degToRad(15.f);
|
||||
}
|
||||
|
@ -559,17 +712,29 @@ bool CElitePirate::AggressionCheck(CStateManager& mgr, float arg) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool CElitePirate::ShouldTaunt(CStateManager& mgr, float arg) { return CAi::ShouldTaunt(mgr, arg); }
|
||||
bool CElitePirate::ShouldTaunt(CStateManager& mgr, float) { return x7bc_tauntTimer <= 0.f; }
|
||||
|
||||
bool CElitePirate::ShouldFire(CStateManager& mgr, float arg) { return CAi::ShouldFire(mgr, arg); }
|
||||
bool CElitePirate::ShouldFire(CStateManager& mgr, float) { return ShouldFireFromLauncher(mgr, x772_launcherId); }
|
||||
|
||||
bool CElitePirate::ShotAt(CStateManager& mgr, float arg) { return x988_27_; }
|
||||
bool CElitePirate::ShotAt(CStateManager& mgr, float) { return x988_27_; }
|
||||
|
||||
bool CElitePirate::ShouldSpecialAttack(CStateManager& mgr, float arg) { return CAi::ShouldSpecialAttack(mgr, arg); }
|
||||
bool CElitePirate::ShouldSpecialAttack(CStateManager& mgr, float) {
|
||||
if (x7b8_attackTimer <= 0.f && GetAreaIdAlways() == mgr.GetPlayer().GetAreaIdAlways()) {
|
||||
const zeus::CVector3f& dist = mgr.GetPlayer().GetAimPosition(mgr, 0.f) - GetTranslation();
|
||||
float magSquared = dist.magSquared();
|
||||
if (x2fc_minAttackRange * x2fc_minAttackRange <= magSquared &&
|
||||
magSquared <= x300_maxAttackRange * x300_maxAttackRange) {
|
||||
return std::abs(dist.z()) < 3.f;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CElitePirate::ShouldCallForBackup(CStateManager& mgr, float arg) { return CAi::ShouldCallForBackup(mgr, arg); }
|
||||
bool CElitePirate::ShouldCallForBackup(CStateManager& mgr, float) {
|
||||
return ShouldCallForBackupFromLauncher(mgr, x772_launcherId);
|
||||
}
|
||||
|
||||
CPathFindSearch* CElitePirate::GetSearchPath() { return CPatterned::GetSearchPath(); }
|
||||
CPathFindSearch* CElitePirate::GetSearchPath() { return &x7d0_pathFindSearch; }
|
||||
|
||||
void CElitePirate::SetupHealthInfo(CStateManager& mgr) {
|
||||
const CHealthInfo* const health = HealthInfo(mgr);
|
||||
|
@ -732,16 +897,17 @@ void CElitePirate::CreateGrenadeLauncher(CStateManager& mgr, TUniqueId uid) {
|
|||
}
|
||||
CModelData mData(CAnimRes(params.GetACSFile(), params.GetCharacter(), GetModelData()->GetScale(),
|
||||
params.GetInitialAnimation(), true));
|
||||
SGrenadeLauncherData transfer{x5d8_data.xd8_, x5d8_data.xa8_, x5d8_data.xc8_, x5d8_data.xcc_, x5d8_data.xd0_,
|
||||
SBouncyGrenadeData grenadeData{x5d8_data.xd8_, x5d8_data.xa8_, x5d8_data.xc8_, x5d8_data.xcc_, x5d8_data.xd0_,
|
||||
x5d8_data.xd4_, x5d8_data.xf0_, x5d8_data.xf4_, x5d8_data.xf6_};
|
||||
CGrenadeLauncherData launcherData{transfer, x5d8_data.xa4_, x5d8_data.x9c_, x5d8_data.xa0_, x5d8_data.xe0_};
|
||||
CGrenadeLauncherData launcherData{grenadeData, x5d8_data.xa4_, x5d8_data.x9c_, x5d8_data.xa0_,
|
||||
x5d8_data.xe0_trajectoryInfo};
|
||||
mgr.AddObject(new CGrenadeLauncher(uid, "Grenade Launcher", {GetAreaIdAlways(), CEntity::NullConnectionList},
|
||||
GetTransform(), std::move(mData), mData.GetBounds(GetTransform().getRotation()),
|
||||
CHealthInfo(x5d8_data.xc4_, 10.f), x56c_vulnerability,
|
||||
CHealthInfo(x5d8_data.xc4_launcherHp, 10.f), x56c_vulnerability,
|
||||
x5d8_data.x28_launcherActParams, GetUniqueId(), launcherData, 0.f));
|
||||
}
|
||||
|
||||
void CElitePirate::sub_80227464(CStateManager& mgr, TUniqueId uid) {
|
||||
void CElitePirate::ApplyDamageToHead(CStateManager& mgr, TUniqueId uid) {
|
||||
if (!sub_802273a8()) {
|
||||
return;
|
||||
}
|
||||
|
@ -753,14 +919,15 @@ void CElitePirate::sub_80227464(CStateManager& mgr, TUniqueId uid) {
|
|||
}
|
||||
}
|
||||
|
||||
void CElitePirate::sub_802281d8(CStateManager& mgr, const zeus::CTransform& xf) {
|
||||
if (x7ac_ > 0.f) {
|
||||
void CElitePirate::CreateEnergyAbsorb(CStateManager& mgr, const zeus::CTransform& xf) {
|
||||
if (x7ac_energyAbsorbCooldown > 0.f) {
|
||||
return;
|
||||
}
|
||||
mgr.AddObject(new CExplosion(*x760_, mgr.AllocateUniqueId(), true, {GetAreaIdAlways(), CEntity::NullConnectionList},
|
||||
"Absorb energy Fx", xf, 0, GetModelData()->GetScale(), zeus::skWhite));
|
||||
mgr.AddObject(new CExplosion(*x760_energyAbsorbDesc, mgr.AllocateUniqueId(), true,
|
||||
{GetAreaIdAlways(), CEntity::NullConnectionList}, "Absorb energy Fx", xf, 0,
|
||||
GetModelData()->GetScale(), zeus::skWhite));
|
||||
CSfxManager::AddEmitter(x5d8_data.x24_sfxAbsorb, GetTranslation(), zeus::skUp, false, false, 0x7f, GetAreaIdAlways());
|
||||
x7ac_ = 0.25f;
|
||||
x7ac_energyAbsorbCooldown = 0.25f;
|
||||
}
|
||||
|
||||
void CElitePirate::UpdateHealthInfo(CStateManager& mgr, TUniqueId uid) {
|
||||
|
@ -768,7 +935,7 @@ void CElitePirate::UpdateHealthInfo(CStateManager& mgr, TUniqueId uid) {
|
|||
if (uid != kInvalidUniqueId) {
|
||||
if (TCastToPtr<CCollisionActor> actor = mgr.ObjectById(uid)) {
|
||||
auto actHealth = actor->HealthInfo(mgr);
|
||||
actHealth->SetHP(x5d8_data.xc4_);
|
||||
actHealth->SetHP(x5d8_data.xc4_launcherHp);
|
||||
actHealth->SetKnockbackResistance(health->GetKnockbackResistance());
|
||||
actor->SetDamageVulnerability(x56c_vulnerability);
|
||||
}
|
||||
|
@ -804,11 +971,131 @@ void CElitePirate::sub_80228634(CStateManager& mgr) {
|
|||
|
||||
void CElitePirate::sub_802285c4(CStateManager& mgr) {
|
||||
if (mgr.GetActiveRandom()->Float() > x5d8_data.x10_) {
|
||||
x7b8_ = x308_attackTimeVariation * mgr.GetActiveRandom()->Float() + x304_averageAttackTime;
|
||||
x7b8_attackTimer = x308_attackTimeVariation * mgr.GetActiveRandom()->Float() + x304_averageAttackTime;
|
||||
}
|
||||
}
|
||||
|
||||
zeus::CVector3f CElitePirate::SUnknownStruct::sub_802a07f0(const zeus::CVector3f& v1, const zeus::CVector3f& v2) {
|
||||
void CElitePirate::sub_80227a90(CStateManager& mgr) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CElitePirate::sub_802277e0(CStateManager& mgr, float dt) {
|
||||
if (!x988_27_ || x450_bodyController->IsFrozen()) {
|
||||
return;
|
||||
}
|
||||
x7c4_ += dt;
|
||||
if (x7c4_ < 3.f) {
|
||||
return;
|
||||
}
|
||||
if (x450_bodyController->GetCurrentStateId() != pas::EAnimationState::Turn &&
|
||||
x450_bodyController->GetBodyStateInfo().GetCurrentState()->IsMoving()) {
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(
|
||||
CBCAdditiveReactionCmd(pas::EAdditiveReactionType::Six, 1.f, false));
|
||||
} else {
|
||||
bool b = false;
|
||||
if (sub_802273a8()) {
|
||||
if (TCastToConstPtr<CCollisionActor> actor = mgr.GetObjectById(x770_collisionHeadId)) {
|
||||
float z = actor->GetTranslation().z();
|
||||
b = z - 0.5f * (z - GetTranslation().z()) <= mgr.GetPlayer().GetTranslation().z();
|
||||
}
|
||||
}
|
||||
b = b || TooClose(mgr, 0.f);
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(
|
||||
CBCAdditiveReactionCmd(b ? pas::EAdditiveReactionType::Seven : pas::EAdditiveReactionType::Five, 1.f, false));
|
||||
}
|
||||
x7c4_ = 0.f;
|
||||
}
|
||||
|
||||
bool CElitePirate::sub_80229208() {
|
||||
if (x450_bodyController->GetLocomotionType() != pas::ELocomotionType::Crouch) {
|
||||
return false;
|
||||
}
|
||||
const pas::EAnimationState state = x450_bodyController->GetCurrentStateId();
|
||||
return state == pas::EAnimationState::Locomotion || state == pas::EAnimationState::Turn;
|
||||
}
|
||||
|
||||
void CElitePirate::sub_80228e50(float dt) {
|
||||
if (x7b8_attackTimer > 0.f) {
|
||||
x7b8_attackTimer -= dt;
|
||||
}
|
||||
if (x7ac_energyAbsorbCooldown > 0.f) {
|
||||
x7ac_energyAbsorbCooldown -= dt;
|
||||
}
|
||||
}
|
||||
|
||||
void CElitePirate::sub_80228798() {
|
||||
const zeus::CVector3f& pos = GetTranslation();
|
||||
if (x7d0_pathFindSearch.OnPath(pos) == CPathFindSearch::EResult::Success) {
|
||||
x8c0_.Clear();
|
||||
}
|
||||
x8c0_.AddValue(pos);
|
||||
}
|
||||
|
||||
void CElitePirate::sub_802289dc(CStateManager& mgr, TUniqueId& uid, std::string_view name) {
|
||||
if (uid == kInvalidUniqueId) {
|
||||
return;
|
||||
}
|
||||
CActor* actor = static_cast<CActor*>(mgr.ObjectById(uid));
|
||||
if (actor == nullptr) {
|
||||
uid = kInvalidUniqueId;
|
||||
return;
|
||||
}
|
||||
actor->SetTransform(GetLctrTransform(name));
|
||||
}
|
||||
|
||||
void CElitePirate::sub_80228e84(CStateManager& mgr) {
|
||||
float hp = HealthInfo(mgr)->GetHP();
|
||||
if (sub_802273a8()) {
|
||||
if (TCastToPtr<CCollisionActor> actor = mgr.ObjectById(x770_collisionHeadId)) {
|
||||
float headHp = actor->HealthInfo(mgr)->GetHP();
|
||||
HealthInfo(mgr)->SetHP(hp - (hp - headHp));
|
||||
*actor->HealthInfo(mgr) = *HealthInfo(mgr); // TODO does this work?
|
||||
}
|
||||
}
|
||||
if (HealthInfo(mgr)->GetHP() <= 0.f) {
|
||||
Death(mgr, zeus::skZero3f, EScriptObjectState::DeathRattle);
|
||||
RemoveMaterial(EMaterialTypes::Orbit, EMaterialTypes::Target, mgr);
|
||||
}
|
||||
}
|
||||
|
||||
void CElitePirate::ExtendTouchBounds(CStateManager& mgr, const rstl::reserved_vector<TUniqueId, 7>& uids,
|
||||
const zeus::CVector3f& vec) {
|
||||
for (const TUniqueId uid : uids) {
|
||||
if (TCastToPtr<CCollisionActor> actor = mgr.ObjectById(uid)) {
|
||||
actor->SetExtendedTouchBounds(vec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CElitePirate::ShouldFireFromLauncher(CStateManager& mgr, TUniqueId launcherId) {
|
||||
if (x7b8_attackTimer <= 0.f && launcherId != kInvalidUniqueId) {
|
||||
const CActor* launcher = static_cast<const CActor*>(mgr.GetObjectById(launcherId));
|
||||
if (launcher != nullptr) {
|
||||
const zeus::CVector3f& aim = mgr.GetPlayer().GetAimPosition(mgr, 0.f);
|
||||
if (x300_maxAttackRange * x300_maxAttackRange <= (aim - GetTranslation()).magSquared() && !ShouldTurn(mgr, 0.f)) {
|
||||
const zeus::CVector3f& origin = sub_80228864(launcher);
|
||||
if (!IsPatternObstructed(mgr, origin, aim)) {
|
||||
const zeus::CVector3f& target = CGrenadeLauncher::GrenadeTarget(mgr);
|
||||
float angleOut = x5d8_data.xe0_trajectoryInfo.x8_angleMin, velocityOut = x5d8_data.xe0_trajectoryInfo.x0_;
|
||||
CGrenadeLauncher::CalculateGrenadeTrajectory(target, origin, x5d8_data.xe0_trajectoryInfo, angleOut,
|
||||
velocityOut);
|
||||
const zeus::CVector3f& rot = GetTransform().rotate({0.f, std::cos(angleOut), std::sin(angleOut)});
|
||||
return !CPatterned::IsPatternObstructed(mgr, target, target + (7.5f * rot));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CElitePirate::ShouldCallForBackupFromLauncher(CStateManager& mgr, TUniqueId uid) {
|
||||
if (!x988_30_ && uid == kInvalidUniqueId && x5d8_data.x11e_) {
|
||||
return x7a8_ >= 3.f;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
zeus::CVector3f CElitePirate::SUnknownStruct::GetValue(const zeus::CVector3f& v1, const zeus::CVector3f& v2) {
|
||||
while (x4_.size()) {
|
||||
const zeus::CVector3f v = x4_[x4_.size() - 1] - v1;
|
||||
if (v.dot(v2) > 0.f && v.isMagnitudeSafe()) {
|
||||
|
@ -818,4 +1105,17 @@ zeus::CVector3f CElitePirate::SUnknownStruct::sub_802a07f0(const zeus::CVector3f
|
|||
}
|
||||
return zeus::skZero3f;
|
||||
}
|
||||
|
||||
void CElitePirate::SUnknownStruct::AddValue(const zeus::CVector3f& vec) {
|
||||
if (x4_.size() > 15) {
|
||||
return;
|
||||
}
|
||||
if (x4_.empty()) {
|
||||
x4_.emplace_back(vec);
|
||||
return;
|
||||
}
|
||||
if (x4_[x4_.size() - 1].magSquared() > x0_) {
|
||||
x4_.emplace_back(vec);
|
||||
}
|
||||
}
|
||||
} // namespace urde::MP1
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "Runtime/Character/CBoneTracking.hpp"
|
||||
#include "Runtime/Collision/CJointCollisionDescription.hpp"
|
||||
#include "Runtime/MP1/World/CGrenadeLauncher.hpp"
|
||||
#include "Runtime/MP1/World/CShockWave.hpp"
|
||||
#include "Runtime/World/CActorParameters.hpp"
|
||||
#include "Runtime/World/CAnimationParameters.hpp"
|
||||
|
@ -14,8 +15,8 @@ class CGenDescription;
|
|||
namespace MP1 {
|
||||
class CElitePirateData {
|
||||
public:
|
||||
float x0_;
|
||||
float x4_;
|
||||
float x0_tauntInterval;
|
||||
float x4_tauntVariance;
|
||||
float x8_;
|
||||
float xc_;
|
||||
float x10_;
|
||||
|
@ -23,20 +24,20 @@ public:
|
|||
float x18_;
|
||||
float x1c_;
|
||||
CAssetId x20_;
|
||||
s16 x24_sfxAbsorb;
|
||||
u16 x24_sfxAbsorb;
|
||||
CActorParameters x28_launcherActParams;
|
||||
CAnimationParameters x90_launcherAnimParams;
|
||||
CAssetId x9c_;
|
||||
u16 xa0_;
|
||||
CAssetId xa4_;
|
||||
CDamageInfo xa8_;
|
||||
float xc4_;
|
||||
float xc4_launcherHp;
|
||||
CAssetId xc8_;
|
||||
CAssetId xcc_;
|
||||
CAssetId xd0_;
|
||||
CAssetId xd4_;
|
||||
CHealthInfo xd8_; // FIXME probably wrong type
|
||||
zeus::CQuaternion xe0_; // FIXME probably wrong type
|
||||
SGrenadeUnknownStruct xd8_;
|
||||
SGrenadeTrajectoryInfo xe0_trajectoryInfo;
|
||||
CAssetId xf0_;
|
||||
u16 xf4_;
|
||||
u16 xf6_;
|
||||
|
@ -61,10 +62,20 @@ class CElitePirate : public CPatterned {
|
|||
float x0_;
|
||||
rstl::reserved_vector<zeus::CVector3f, 16> x4_;
|
||||
SUnknownStruct(float f) : x0_(f * f) {}
|
||||
zeus::CVector3f sub_802a07f0(const zeus::CVector3f& v1, const zeus::CVector3f& v2);
|
||||
zeus::CVector3f GetValue(const zeus::CVector3f& v1, const zeus::CVector3f& v2);
|
||||
void AddValue(const zeus::CVector3f& vec);
|
||||
void Clear() { x4_.clear(); }
|
||||
};
|
||||
|
||||
s32 x568_ = -1;
|
||||
enum class EState {
|
||||
Invalid = -1,
|
||||
Zero = 0,
|
||||
One = 1,
|
||||
Two = 2,
|
||||
Over = 3,
|
||||
};
|
||||
|
||||
EState x568_ = EState::Invalid;
|
||||
CDamageVulnerability x56c_vulnerability;
|
||||
std::unique_ptr<CCollisionActorManager> x5d4_collisionActorMgr1;
|
||||
CElitePirateData x5d8_data;
|
||||
|
@ -72,7 +83,7 @@ class CElitePirate : public CPatterned {
|
|||
std::unique_ptr<CCollisionActorManager> x730_collisionActorMgr2;
|
||||
s32 x734_;
|
||||
CCollidableAABox x738_;
|
||||
std::optional<TLockedToken<CGenDescription>> x760_;
|
||||
std::optional<TLockedToken<CGenDescription>> x760_energyAbsorbDesc;
|
||||
TUniqueId x770_collisionHeadId = kInvalidUniqueId;
|
||||
TUniqueId x772_launcherId = kInvalidUniqueId;
|
||||
rstl::reserved_vector<TUniqueId, 7> x774_collisionRJointIds;
|
||||
|
@ -81,14 +92,14 @@ class CElitePirate : public CPatterned {
|
|||
float x7a0_;
|
||||
float x7a4_ = 1.f;
|
||||
float x7a8_ = 0.f;
|
||||
float x7ac_ = 0.f;
|
||||
float x7ac_energyAbsorbCooldown = 0.f;
|
||||
float x7b0_ = 1.f;
|
||||
float x7b4_hp = 0.f;
|
||||
float x7b8_ = 0.f;
|
||||
float x7bc_ = 0.f;
|
||||
float x7b8_attackTimer = 0.f;
|
||||
float x7bc_tauntTimer = 0.f;
|
||||
float x7c0_ = 0.f;
|
||||
float x7c4_ = 0.f;
|
||||
s32 x7c8_ = -1;
|
||||
s32 x7c8_currAnimId = -1;
|
||||
s32 x7cc_ = 0;
|
||||
CPathFindSearch x7d0_pathFindSearch;
|
||||
zeus::CVector3f x8b4_;
|
||||
|
@ -121,33 +132,34 @@ public:
|
|||
zeus::CVector3f GetAimPosition(const CStateManager& mgr, float) const override;
|
||||
void DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) override;
|
||||
const CCollisionPrimitive* GetCollisionPrimitive() const override;
|
||||
void KnockBack(const zeus::CVector3f&, CStateManager&, const CDamageInfo& info, EKnockBackType type, bool inDeferred,
|
||||
float magnitude) override;
|
||||
void KnockBack(const zeus::CVector3f&, CStateManager& mgr, const CDamageInfo& info, EKnockBackType type,
|
||||
bool inDeferred, float magnitude) override;
|
||||
void TakeDamage(const zeus::CVector3f&, float arg) override;
|
||||
void Patrol(CStateManager&, EStateMsg msg, float dt) override;
|
||||
void PathFind(CStateManager&, EStateMsg msg, float dt) override;
|
||||
void TargetPatrol(CStateManager&, EStateMsg msg, float dt) override;
|
||||
void Halt(CStateManager&, EStateMsg msg, float dt) override;
|
||||
void Run(CStateManager&, EStateMsg msg, float dt) override;
|
||||
void Generate(CStateManager&, EStateMsg msg, float dt) override;
|
||||
void Attack(CStateManager&, EStateMsg msg, float dt) override;
|
||||
void Taunt(CStateManager&, EStateMsg msg, float dt) override;
|
||||
void ProjectileAttack(CStateManager&, EStateMsg msg, float dt) override;
|
||||
void SpecialAttack(CStateManager&, EStateMsg msg, float dt) override;
|
||||
void CallForBackup(CStateManager&, EStateMsg msg, float dt) override;
|
||||
bool TooClose(CStateManager&, float arg) override;
|
||||
bool InDetectionRange(CStateManager&, float arg) override;
|
||||
bool SpotPlayer(CStateManager&, float arg) override;
|
||||
bool AnimOver(CStateManager&, float arg) override;
|
||||
bool ShouldAttack(CStateManager&, float arg) override;
|
||||
bool InPosition(CStateManager&, float arg) override;
|
||||
bool ShouldTurn(CStateManager&, float arg) override;
|
||||
bool AggressionCheck(CStateManager&, float arg) override;
|
||||
bool ShouldTaunt(CStateManager&, float arg) override;
|
||||
bool ShouldFire(CStateManager&, float arg) override;
|
||||
bool ShotAt(CStateManager&, float arg) override;
|
||||
bool ShouldSpecialAttack(CStateManager&, float arg) override;
|
||||
bool ShouldCallForBackup(CStateManager&, float arg) override;
|
||||
void Patrol(CStateManager& mgr, EStateMsg msg, float dt) override;
|
||||
void PathFind(CStateManager& mgr, EStateMsg msg, float dt) override;
|
||||
void TargetPatrol(CStateManager& mgr, EStateMsg msg, float dt) override;
|
||||
void Halt(CStateManager& mgr, EStateMsg msg, float dt) override;
|
||||
void Run(CStateManager& mgr, EStateMsg msg, float dt) override;
|
||||
void Generate(CStateManager& mgr, EStateMsg msg, float dt) override;
|
||||
void Attack(CStateManager& mgr, EStateMsg msg, float dt) override;
|
||||
void Taunt(CStateManager& mgr, EStateMsg msg, float dt) override;
|
||||
void ProjectileAttack(CStateManager& mgr, EStateMsg msg, float dt) override;
|
||||
void SpecialAttack(CStateManager& mgr, EStateMsg msg, float dt) override;
|
||||
void CallForBackup(CStateManager& mgr, EStateMsg msg, float dt) override;
|
||||
void Cover(CStateManager& mgr, EStateMsg msg, float dt) override;
|
||||
bool TooClose(CStateManager& mgr, float arg) override;
|
||||
bool InDetectionRange(CStateManager& mgr, float arg) override;
|
||||
bool SpotPlayer(CStateManager& mgr, float arg) override;
|
||||
bool AnimOver(CStateManager& mgr, float arg) override;
|
||||
bool ShouldAttack(CStateManager& mgr, float arg) override;
|
||||
bool InPosition(CStateManager& mgr, float arg) override;
|
||||
bool ShouldTurn(CStateManager& mgr, float arg) override;
|
||||
bool AggressionCheck(CStateManager& mgr, float arg) override;
|
||||
bool ShouldTaunt(CStateManager& mgr, float arg) override;
|
||||
bool ShouldFire(CStateManager& mgr, float arg) override;
|
||||
bool ShotAt(CStateManager& mgr, float arg) override;
|
||||
bool ShouldSpecialAttack(CStateManager& mgr, float arg) override;
|
||||
bool ShouldCallForBackup(CStateManager& mgr, float arg) override;
|
||||
CPathFindSearch* GetSearchPath() override;
|
||||
virtual bool sub_802273a8() const { return true; }
|
||||
virtual bool sub_802273b0() const { return true; }
|
||||
|
@ -169,14 +181,25 @@ private:
|
|||
void SetupCollisionActorInfo(CStateManager& mgr);
|
||||
bool IsArmClawCollider(std::string_view name, std::string_view locator, const SJointInfo* info, size_t infoCount);
|
||||
void CreateGrenadeLauncher(CStateManager& mgr, TUniqueId uid);
|
||||
void sub_80227464(CStateManager& mgr, TUniqueId uid);
|
||||
void sub_802281d8(CStateManager& mgr, const zeus::CTransform& xf);
|
||||
void ApplyDamageToHead(CStateManager& mgr, TUniqueId uid);
|
||||
void CreateEnergyAbsorb(CStateManager& mgr, const zeus::CTransform& xf);
|
||||
void UpdateHealthInfo(CStateManager& mgr, TUniqueId uid);
|
||||
void sub_80228920(CStateManager& mgr, bool b, TUniqueId uid);
|
||||
zeus::CVector3f sub_80228864(const CActor* actor) const;
|
||||
bool sub_80227430(const CDamageInfo& info) const;
|
||||
void sub_80228634(CStateManager& mgr);
|
||||
void sub_802285c4(CStateManager& mgr);
|
||||
void sub_80227a90(CStateManager& mgr);
|
||||
void sub_802277e0(CStateManager& mgr, float dt);
|
||||
bool sub_80229208();
|
||||
void sub_80228e50(float dt);
|
||||
void sub_80228798();
|
||||
void sub_802289dc(CStateManager& mgr, TUniqueId& uid, std::string_view name);
|
||||
void sub_80228e84(CStateManager& mgr);
|
||||
void ExtendTouchBounds(CStateManager& mgr, const rstl::reserved_vector<TUniqueId, 7>& uids,
|
||||
const zeus::CVector3f& vec);
|
||||
bool ShouldFireFromLauncher(CStateManager& mgr, TUniqueId launcherId);
|
||||
bool ShouldCallForBackupFromLauncher(CStateManager& mgr, TUniqueId uid);
|
||||
};
|
||||
} // namespace MP1
|
||||
} // namespace urde
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
#include "Runtime/MP1/World/CGrenadeLauncher.hpp"
|
||||
|
||||
#include "Runtime/CSimplePool.hpp"
|
||||
#include "Runtime/GameGlobalObjects.hpp"
|
||||
#include "Runtime/Character/CPASAnimParm.hpp"
|
||||
#include "Runtime/Character/CPASAnimParmData.hpp"
|
||||
#include "Runtime/CSimplePool.hpp"
|
||||
#include "Runtime/CStateManager.hpp"
|
||||
#include "Runtime/GameGlobalObjects.hpp"
|
||||
#include "Runtime/World/CPlayer.hpp"
|
||||
|
||||
namespace urde {
|
||||
namespace MP1 {
|
||||
|
@ -30,5 +32,54 @@ CGrenadeLauncher::CGrenadeLauncher(TUniqueId uid, std::string_view name, const C
|
|||
x3c8_animIds[i] = result.second;
|
||||
}
|
||||
}
|
||||
|
||||
zeus::CVector3f CGrenadeLauncher::GrenadeTarget(const CStateManager& mgr) {
|
||||
const zeus::CVector3f& aim = mgr.GetPlayer().GetAimPosition(mgr, 1.f);
|
||||
if (mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Unmorphed) {
|
||||
return aim - zeus::CVector3f{0.f, 0.f, 0.5f * mgr.GetPlayer().GetEyeHeight()};
|
||||
}
|
||||
return aim;
|
||||
}
|
||||
|
||||
void CGrenadeLauncher::CalculateGrenadeTrajectory(const zeus::CVector3f& target, const zeus::CVector3f& origin,
|
||||
const SGrenadeTrajectoryInfo& info, float& angleOut,
|
||||
float& velocityOut) {
|
||||
float angle = info.x8_angleMin;
|
||||
float velocity = info.x0_;
|
||||
float delta = std::max(0.01f, 0.1f * (info.xc_angleMax - info.x8_angleMin));
|
||||
zeus::CVector3f dist = target - origin;
|
||||
float distXYMag = dist.toVec2f().magnitude();
|
||||
float qwSq = info.x0_ * info.x0_;
|
||||
float qxSq = info.x4_ * info.x4_;
|
||||
float gravAdj = distXYMag * ((0.5f * CPhysicsActor::GravityConstant()) * distXYMag);
|
||||
float currAngle = info.x8_angleMin;
|
||||
float leastResult = FLT_MAX;
|
||||
while (info.xc_angleMax >= currAngle) {
|
||||
float cos = std::cos(currAngle);
|
||||
float sin = std::sin(currAngle);
|
||||
float result = (distXYMag * (cos * sin) - (dist.z() * (cos * cos)));
|
||||
if (result > FLT_EPSILON) {
|
||||
float div = gravAdj / result;
|
||||
if (qwSq <= result && result <= qxSq) {
|
||||
angle = currAngle;
|
||||
velocity = std::sqrt(div);
|
||||
break;
|
||||
}
|
||||
if (result <= qxSq) {
|
||||
result = qwSq - result;
|
||||
} else {
|
||||
result = result - qxSq;
|
||||
}
|
||||
if (result < leastResult) {
|
||||
angle = currAngle;
|
||||
velocity = std::sqrt(div);
|
||||
leastResult = result;
|
||||
}
|
||||
}
|
||||
currAngle += delta;
|
||||
}
|
||||
angleOut = angle;
|
||||
velocityOut = velocity;
|
||||
}
|
||||
} // namespace MP1
|
||||
} // namespace urde
|
||||
|
|
|
@ -22,8 +22,28 @@
|
|||
|
||||
namespace urde {
|
||||
namespace MP1 {
|
||||
struct SGrenadeLauncherData {
|
||||
CHealthInfo x0_healthInfo;
|
||||
struct SGrenadeTrajectoryInfo {
|
||||
float x0_;
|
||||
float x4_;
|
||||
float x8_angleMin;
|
||||
float xc_angleMax;
|
||||
|
||||
SGrenadeTrajectoryInfo(CInputStream& in)
|
||||
: x0_(in.readFloatBig())
|
||||
, x4_(in.readFloatBig())
|
||||
, x8_angleMin(zeus::degToRad(in.readFloatBig()))
|
||||
, xc_angleMax(zeus::degToRad(in.readFloatBig())) {}
|
||||
};
|
||||
|
||||
struct SGrenadeUnknownStruct {
|
||||
float x0_mass;
|
||||
float x4_;
|
||||
|
||||
SGrenadeUnknownStruct(CInputStream& in) : x0_mass(in.readFloatBig()), x4_(in.readFloatBig()) {}
|
||||
};
|
||||
|
||||
struct SBouncyGrenadeData {
|
||||
SGrenadeUnknownStruct x0_;
|
||||
CDamageInfo x8_damageInfo;
|
||||
CAssetId x24_;
|
||||
CAssetId x28_;
|
||||
|
@ -33,30 +53,22 @@ struct SGrenadeLauncherData {
|
|||
u16 x38_;
|
||||
u16 x3a_;
|
||||
|
||||
SGrenadeLauncherData(const CHealthInfo& healthInfo, const CDamageInfo& damageInfo, CAssetId w1, CAssetId w2,
|
||||
SBouncyGrenadeData(const SGrenadeUnknownStruct& unkStruct, const CDamageInfo& damageInfo, CAssetId w1, CAssetId w2,
|
||||
CAssetId w3, CAssetId w4, CAssetId w5, u16 s1, u16 s2)
|
||||
: x0_healthInfo(healthInfo)
|
||||
, x8_damageInfo(damageInfo)
|
||||
, x24_(w1)
|
||||
, x28_(w2)
|
||||
, x2c_(w3)
|
||||
, x30_(w4)
|
||||
, x34_(w5)
|
||||
, x38_(s1)
|
||||
, x3a_(s2){};
|
||||
: x0_(unkStruct), x8_damageInfo(damageInfo), x24_(w1), x28_(w2), x2c_(w3), x30_(w4), x34_(w5), x38_(s1), x3a_(s2){};
|
||||
};
|
||||
|
||||
class CGrenadeLauncherData {
|
||||
public:
|
||||
SGrenadeLauncherData x0_;
|
||||
SBouncyGrenadeData x0_;
|
||||
CAssetId x3c_;
|
||||
CAssetId x40_;
|
||||
u16 x44_sfx;
|
||||
zeus::CQuaternion x48_quat;
|
||||
SGrenadeTrajectoryInfo x48_trajectoryInfo;
|
||||
|
||||
CGrenadeLauncherData(const SGrenadeLauncherData& data, CAssetId w1, CAssetId w2, u16 sfx,
|
||||
const zeus::CQuaternion& quat)
|
||||
: x0_(data), x3c_(w1), x40_(w2), x44_sfx(sfx), x48_quat(quat){};
|
||||
CGrenadeLauncherData(const SBouncyGrenadeData& data, CAssetId w1, CAssetId w2, u16 sfx,
|
||||
const SGrenadeTrajectoryInfo& trajectoryInfo)
|
||||
: x0_(data), x3c_(w1), x40_(w2), x44_sfx(sfx), x48_trajectoryInfo(trajectoryInfo){};
|
||||
};
|
||||
|
||||
class CGrenadeLauncher : public CPhysicsActor {
|
||||
|
@ -92,16 +104,20 @@ public:
|
|||
const CGrenadeLauncherData& data, float f1);
|
||||
|
||||
void Accept(IVisitor& visitor) override { visitor.Visit(this); }
|
||||
void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override;
|
||||
void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const override;
|
||||
// void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override;
|
||||
// void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const override;
|
||||
const CCollisionPrimitive* GetCollisionPrimitive() const override { return &x328_cSphere; }
|
||||
const CDamageVulnerability* GetDamageVulnerability() const override { return &x264_vulnerability; }
|
||||
std::optional<zeus::CAABox> GetTouchBounds() const override;
|
||||
CHealthInfo* HealthInfo(CStateManager& mgr) override;
|
||||
void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override;
|
||||
void Render(const CStateManager& mgr) const override;
|
||||
void Think(float dt, CStateManager& mgr) override;
|
||||
void Touch(CActor& act, CStateManager& mgr) override;
|
||||
// std::optional<zeus::CAABox> GetTouchBounds() const override;
|
||||
// CHealthInfo* HealthInfo(CStateManager& mgr) override;
|
||||
// void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override;
|
||||
// void Render(const CStateManager& mgr) const override;
|
||||
// void Think(float dt, CStateManager& mgr) override;
|
||||
// void Touch(CActor& act, CStateManager& mgr) override;
|
||||
|
||||
static zeus::CVector3f GrenadeTarget(const CStateManager& mgr);
|
||||
static void CalculateGrenadeTrajectory(const zeus::CVector3f& target, const zeus::CVector3f& origin,
|
||||
const SGrenadeTrajectoryInfo& info, float& angleOut, float& velocityOut);
|
||||
|
||||
protected:
|
||||
void UpdateCollision();
|
||||
|
|
Loading…
Reference in New Issue