#include "Runtime/Weapon/CProjectileInfo.hpp" #include "Runtime/CSimplePool.hpp" #include "Runtime/GameGlobalObjects.hpp" #include "Runtime/Character/CSteeringBehaviors.hpp" #include "Runtime/Weapon/CProjectileWeapon.hpp" #include "Runtime/World/CDamageInfo.hpp" #include "Runtime/World/CPlayer.hpp" namespace metaforce { CProjectileInfo::CProjectileInfo(metaforce::CInputStream& in) : x0_weaponDescription(g_SimplePool->GetObj({SBIG('WPSC'), CAssetId(in)})), xc_damageInfo(in) {} CProjectileInfo::CProjectileInfo(CAssetId proj, const CDamageInfo& dInfo) : x0_weaponDescription(g_SimplePool->GetObj({SBIG('WPSC'), proj})), xc_damageInfo(dInfo) {} zeus::CVector3f CProjectileInfo::PredictInterceptPos(const zeus::CVector3f& gunPos, const zeus::CVector3f& aimPos, const CPlayer& player, bool gravity, float speed, float dt) { zeus::CVector3f ret; const zeus::CVector3f playerVel = player.GetDampedClampedVelocityWR(); const zeus::CVector3f gravVec(0.f, 0.f, player.GetGravity()); bool result = false; switch (player.GetOrbitState()) { case CPlayer::EPlayerOrbitState::OrbitObject: case CPlayer::EPlayerOrbitState::OrbitPoint: case CPlayer::EPlayerOrbitState::OrbitCarcass: case CPlayer::EPlayerOrbitState::ForcedOrbitObject: case CPlayer::EPlayerOrbitState::Grapple: { if (gravity && player.GetPlayerMovementState() == CPlayer::EPlayerMovementState::ApplyJump) { result = CSteeringBehaviors::ProjectOrbitalIntersection(gunPos, speed, dt, aimPos, playerVel, gravVec, player.GetOrbitPoint(), ret); break; } zeus::CVector3f vel; if (playerVel.canBeNormalized()) { vel = playerVel.normalized() * player.GetAverageSpeed(); } else { vel = playerVel; } result = CSteeringBehaviors::ProjectOrbitalIntersection(gunPos, speed, dt, aimPos, vel, player.GetOrbitPoint(), ret); break; } case CPlayer::EPlayerOrbitState::NoOrbit: if (gravity && player.GetPlayerMovementState() == CPlayer::EPlayerMovementState::ApplyJump) { result = CSteeringBehaviors::ProjectLinearIntersection(gunPos, speed, aimPos, playerVel, gravVec, ret); } else { result = CSteeringBehaviors::ProjectLinearIntersection(gunPos, speed, aimPos, playerVel, ret); } break; } if (!result) { ret = playerVel * 1.5f + aimPos; } return ret; } float CProjectileInfo::GetProjectileSpeed() const { auto wpsc = x0_weaponDescription; if (wpsc->x4_IVEC) { zeus::CVector3f vec; wpsc->x4_IVEC->GetValue(0, vec); return vec.magnitude() / CProjectileWeapon::GetTickPeriod(); } return 45000.0f; } zeus::CVector3f CProjectileInfo::PredictInterceptPos(const zeus::CVector3f& gunPos, const zeus::CVector3f& aimPos, const CPlayer& player, bool gravity, float dt) const { return PredictInterceptPos(gunPos, aimPos, player, gravity, GetProjectileSpeed(), dt); } } // namespace metaforce