metaforce/Runtime/Weapon/CProjectileInfo.cpp

78 lines
3.0 KiB
C++
Raw Permalink Normal View History

#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"
2018-06-04 12:30:04 -07:00
2021-04-10 01:42:06 -07:00
namespace metaforce {
2018-06-04 12:30:04 -07:00
2021-04-10 01:42:06 -07:00
CProjectileInfo::CProjectileInfo(metaforce::CInputStream& in)
: x0_weaponDescription(g_SimplePool->GetObj({SBIG('WPSC'), CAssetId(in)})), xc_damageInfo(in) {}
2018-12-07 21:30:43 -08:00
CProjectileInfo::CProjectileInfo(CAssetId proj, const CDamageInfo& dInfo)
: x0_weaponDescription(g_SimplePool->GetObj({SBIG('WPSC'), proj})), xc_damageInfo(dInfo) {}
2018-06-04 12:30:04 -07:00
2018-12-12 23:39:16 -08:00
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;
2018-12-12 23:39:16 -08:00
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()) {
2018-12-12 23:39:16 -08:00
vel = playerVel.normalized() * player.GetAverageSpeed();
} else {
2018-12-12 23:39:16 -08:00
vel = playerVel;
}
2021-06-07 12:29:18 -07:00
result =
CSteeringBehaviors::ProjectOrbitalIntersection(gunPos, speed, dt, aimPos, vel, player.GetOrbitPoint(), ret);
2018-12-12 23:39:16 -08:00
break;
}
case CPlayer::EPlayerOrbitState::NoOrbit:
if (gravity && player.GetPlayerMovementState() == CPlayer::EPlayerMovementState::ApplyJump) {
2018-12-12 23:39:16 -08:00
result = CSteeringBehaviors::ProjectLinearIntersection(gunPos, speed, aimPos, playerVel, gravVec, ret);
} else {
2018-12-12 23:39:16 -08:00
result = CSteeringBehaviors::ProjectLinearIntersection(gunPos, speed, aimPos, playerVel, ret);
}
break;
2018-12-12 23:39:16 -08:00
}
if (!result) {
2018-12-12 23:39:16 -08:00
ret = playerVel * 1.5f + aimPos;
}
2018-12-12 23:39:16 -08:00
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 {
2018-12-12 23:39:16 -08:00
return PredictInterceptPos(gunPos, aimPos, player, gravity, GetProjectileSpeed(), dt);
2018-06-04 12:30:04 -07:00
}
2021-04-10 01:42:06 -07:00
} // namespace metaforce