#include "MP1/World/CRipper.hpp" #include "Collision/CCollidableOBBTreeGroup.hpp" #include "Weapon/CPlayerGun.hpp" #include "World/CActorParameters.hpp" #include "World/CPlayer.hpp" #include "World/CScriptGrapplePoint.hpp" #include "CStateManager.hpp" #include "TCastTo.hpp" namespace urde::MP1 { CRipper::CRipper(TUniqueId uid, std::string_view name, EFlavorType type, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& actParms, const CGrappleParameters& grappleParms) : CPatterned(ECharacter::Ripper, uid, name, type, info, xf, std::move(mData), pInfo, EMovementType::Flyer, EColliderType::One, EBodyType::Flyer, actParms, EKnockBackVariant::Medium) , x568_grappleParams(grappleParms) , x59c_24_muted(false) { SetMaterialFilter(CMaterialFilter::MakeIncludeExclude( {EMaterialTypes::Solid}, {EMaterialTypes::NoStaticCollision, EMaterialTypes::NoPlatformCollision, EMaterialTypes::Platform})); x460_knockBackController.SetAutoResetImpulse(false); x460_knockBackController.SetAnimationStateRange(EKnockBackAnimationState::KnockBack, EKnockBackAnimationState::Hurled); } void CRipper::Think(float dt, CStateManager& mgr) { if (!GetActive()) return; ProcessGrapplePoint(mgr); const CPlayer& pl = mgr.GetPlayer(); CGrappleArm::EArmState armState = pl.GetPlayerGun()->GetGrappleArm().GetAnimState(); if (x598_grapplePoint == kInvalidUniqueId || pl.GetOrbitTargetId() != x598_grapplePoint || pl.GetGrappleState() == CPlayer::EGrappleState::None) { CPatterned::Think(dt, mgr); if (x59c_24_muted) { SetMuted(false); x59c_24_muted = false; } } else { if (armState == CGrappleArm::EArmState::FireGrapple) { CPatterned::Think(dt, mgr); } else if (armState == CGrappleArm::EArmState::IntoGrappleIdle || armState == CGrappleArm::EArmState::Three) { Stop(); if (!x59c_24_muted) { SetMuted(true); x59c_24_muted = true; } } } CPatterned::Think(dt, mgr); } void CRipper::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) { CPatterned::AcceptScriptMsg(msg, uid, mgr); switch (msg) { case EScriptObjectMessage::Deleted: case EScriptObjectMessage::Deactivate: { RemoveGrapplePoint(mgr); RemovePlatform(mgr); break; } case EScriptObjectMessage::Activate: { AddGrapplePoint(mgr); AddPlatform(mgr); break; } case EScriptObjectMessage::Registered: { x450_bodyController->Activate(mgr); AddMaterial(EMaterialTypes::Immovable, mgr); RemoveMaterial(EMaterialTypes::Solid, mgr); if (x3fc_flavor != EFlavorType::One) { AddGrapplePoint(mgr); RemoveMaterial(EMaterialTypes::Orbit, mgr); } AddPlatform(mgr); break; } default: break; } } void CRipper::KnockBack(const zeus::CVector3f& dir, CStateManager& mgr, const CDamageInfo& dInfo, EKnockBackType kb, bool inDeferred, float mag) { CPatterned::KnockBack(dir, mgr, dInfo, kb, inDeferred, mag); } void CRipper::Patrol(CStateManager& mgr, EStateMsg msg, float arg) { x450_bodyController->GetCommandMgr().SetSteeringBlendMode(ESteeringBlendMode::FullSpeed); x450_bodyController->GetCommandMgr().SetSteeringSpeedRange(1.f, 1.f); CPatterned::Patrol(mgr, msg, arg); } void CRipper::ProcessGrapplePoint(CStateManager& mgr) { if (x3fc_flavor == EFlavorType::One || x598_grapplePoint == kInvalidUniqueId) return; if (TCastToPtr gp = mgr.ObjectById(x598_grapplePoint)) { gp->SetTransform(GetTransform()); } } void CRipper::AddGrapplePoint(CStateManager& mgr) { if (x598_grapplePoint != kInvalidUniqueId) return; x598_grapplePoint = mgr.AllocateUniqueId(); mgr.AddObject(new CScriptGrapplePoint(x59a_platformId, "RipperGrapplePoint"sv, CEntityInfo(GetAreaIdAlways(), NullConnectionList), GetTransform(), true, x568_grappleParams)); } void CRipper::RemoveGrapplePoint(CStateManager& mgr) { if (x598_grapplePoint == kInvalidUniqueId) return; mgr.FreeScriptObject(x598_grapplePoint); } void CRipper::AddPlatform(CStateManager& mgr) { if (x59a_platformId != kInvalidUniqueId) return; x59a_platformId = mgr.AllocateUniqueId(); const zeus::CAABox bounds = GetModelData()->GetBounds(GetTransform().getRotation()); mgr.AddObject(new CRipperControlledPlatform(x59a_platformId, GetUniqueId(), "Ripper Controlled Platform"sv, CEntityInfo(GetAreaIdAlways(), NullConnectionList), GetTransform(), bounds, GetActive(), {})); } void CRipper::RemovePlatform(CStateManager& mgr) { if (x59a_platformId == kInvalidUniqueId) return; mgr.FreeScriptObject(x59a_platformId); x59a_platformId = kInvalidUniqueId; } CRipperControlledPlatform::CRipperControlledPlatform( TUniqueId uid, TUniqueId owner, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, const zeus::CAABox& bounds, bool active, const std::optional>& colTree) : CScriptPlatform(uid, name, info, xf, CModelData::CModelDataNull(), CActorParameters::None(), bounds, 0.f, false, 1.f, active, CHealthInfo(FLT_MAX, 10.f), CDamageVulnerability::ImmuneVulnerabilty(), colTree, 0, 1, 1) , x358_owner(owner) , x35c_yaw(GetYaw()) {} }