Additional CPlayer implementations

This commit is contained in:
Jack Andersen 2017-07-26 19:15:51 -10:00
parent 4528a6b60a
commit 473103d41a
7 changed files with 212 additions and 25 deletions

View File

@ -17,6 +17,7 @@ struct ITweakPlayer : ITweak
virtual float GetFluidGravAccel() const=0;
virtual float GetHudLagAmount() const=0;
virtual float GetOrbitNormalDistance() const=0;
virtual float GetOrbitDistanceCompareSignificance() const=0;
virtual uint32_t GetOrbitScreenBoxHalfExtentX(int zone) const=0;
virtual uint32_t GetOrbitScreenBoxHalfExtentY(int zone) const=0;
virtual uint32_t GetOrbitScreenBoxCenterX(int zone) const=0;
@ -42,6 +43,7 @@ struct ITweakPlayer : ITweak
virtual float GetX274() const=0; // x274
virtual float GetX278() const=0; // x278
virtual float GetPlayerBallHalfExtent() const=0; // x27c
virtual float GetOrbitDistanceThreshold() const=0;
virtual float GetGrappleSwingLength() const=0;
virtual float GetGrappleSwingPeriod() const=0;
virtual float GetGrapplePullSpeedMin() const=0;

View File

@ -290,7 +290,7 @@ void CTweakPlayer::read(athena::io::IStreamReader& __dna_reader)
/* x1a0_ */
x1a0_ = __dna_reader.readFloatBig();
/* x1a4_ */
x1a4_ = __dna_reader.readFloatBig();
x1a4_orbitDistanceCompareSignificance = __dna_reader.readFloatBig();
/* x1a8_orbitScreenBoxHalfExtentX[0] */
x1a8_orbitScreenBoxHalfExtentX[0] = __dna_reader.readUint32Big();
/* x1b0_orbitScreenBoxHalfExtentY[0] */
@ -361,8 +361,8 @@ void CTweakPlayer::read(athena::io::IStreamReader& __dna_reader)
x220_ = __dna_reader.readFloatBig();
/* x224_scanningFrameSenseRange */
x224_scanningFrameSenseRange = __dna_reader.readFloatBig();
/* x2a0_ */
x2a0_ = __dna_reader.readFloatBig();
/* x2a0_orbitDistanceThreshold */
x2a0_orbitDistanceThreshold = __dna_reader.readFloatBig();
/* x2a4_grappleSwingLength */
x2a4_grappleSwingLength = __dna_reader.readFloatBig();
/* x2a8_grappleSwingPeriod */
@ -730,7 +730,7 @@ void CTweakPlayer::write(athena::io::IStreamWriter& __dna_writer) const
/* x1a0_ */
__dna_writer.writeFloatBig(x1a0_);
/* x1a4_ */
__dna_writer.writeFloatBig(x1a4_);
__dna_writer.writeFloatBig(x1a4_orbitDistanceCompareSignificance);
/* x1a8_orbitScreenBoxHalfExtentX[0] */
__dna_writer.writeUint32Big(x1a8_orbitScreenBoxHalfExtentX[0]);
/* x1b0_orbitScreenBoxHalfExtentY[0] */
@ -801,8 +801,8 @@ void CTweakPlayer::write(athena::io::IStreamWriter& __dna_writer) const
__dna_writer.writeFloatBig(x220_);
/* x224_scanningFrameSenseRange */
__dna_writer.writeFloatBig(x224_scanningFrameSenseRange);
/* x2a0_ */
__dna_writer.writeFloatBig(x2a0_);
/* x2a0_orbitDistanceThreshold */
__dna_writer.writeFloatBig(x2a0_orbitDistanceThreshold);
/* x2a4_grappleSwingLength */
__dna_writer.writeFloatBig(x2a4_grappleSwingLength);
/* x2a8_grappleSwingPeriod */
@ -1215,7 +1215,7 @@ void CTweakPlayer::read(athena::io::YAMLDocReader& __dna_docin)
/* x1a0_ */
x1a0_ = __dna_docin.readFloat("x1a0_");
/* x1a4_ */
x1a4_ = __dna_docin.readFloat("x1a4_");
x1a4_orbitDistanceCompareSignificance = __dna_docin.readFloat("x1a4_");
/* x1a8_orbitScreenBoxHalfExtentX */
size_t __x1a8_Count;
if (auto v = __dna_docin.enterSubVector("x1a8_orbitScreenBoxHalfExtentX", __x1a8_Count))
@ -1316,8 +1316,8 @@ void CTweakPlayer::read(athena::io::YAMLDocReader& __dna_docin)
x220_ = __dna_docin.readFloat("x220_");
/* x224_scanningFrameSenseRange */
x224_scanningFrameSenseRange = __dna_docin.readFloat("x224_scanningFrameSenseRange");
/* x2a0_ */
x2a0_ = __dna_docin.readFloat("x2a0_");
/* x2a0_orbitDistanceThreshold */
x2a0_orbitDistanceThreshold = __dna_docin.readFloat("x2a0_orbitDistanceThreshold");
/* x2a4_grappleSwingLength */
x2a4_grappleSwingLength = __dna_docin.readFloat("x2a4_grappleSwingLength");
/* x2a8_grappleSwingPeriod */
@ -1721,7 +1721,7 @@ void CTweakPlayer::write(athena::io::YAMLDocWriter& __dna_docout) const
/* x1a0_ */
__dna_docout.writeFloat("x1a0_", x1a0_);
/* x1a4_ */
__dna_docout.writeFloat("x1a4_", x1a4_);
__dna_docout.writeFloat("x1a4_", x1a4_orbitDistanceCompareSignificance);
/* x1a8_orbitScreenBoxHalfExtentX */
if (auto v = __dna_docout.enterSubVector("x1a8_orbitScreenBoxHalfExtentX"))
{
@ -1816,8 +1816,8 @@ void CTweakPlayer::write(athena::io::YAMLDocWriter& __dna_docout) const
__dna_docout.writeFloat("x220_", x220_);
/* x224_scanningFrameSenseRange */
__dna_docout.writeFloat("x224_scanningFrameSenseRange", x224_scanningFrameSenseRange);
/* x2a0_ */
__dna_docout.writeFloat("x2a0_", x2a0_);
/* x2a0_orbitDistanceThreshold */
__dna_docout.writeFloat("x2a0_orbitDistanceThreshold", x2a0_orbitDistanceThreshold);
/* x2a4_grappleSwingLength */
__dna_docout.writeFloat("x2a4_grappleSwingLength", x2a4_grappleSwingLength);
/* x2a8_grappleSwingPeriod */

View File

@ -67,7 +67,7 @@ struct CTweakPlayer : ITweakPlayer
Value<float> x198_;
Value<float> x19c_;
Value<float> x1a0_;
Value<float> x1a4_;
Value<float> x1a4_orbitDistanceCompareSignificance;
Value<atUint32> x1a8_orbitScreenBoxHalfExtentX[2];
Value<atUint32> x1b0_orbitScreenBoxHalfExtentY[2];
Value<atUint32> x1b8_orbitScreenBoxCenterX[2];
@ -147,7 +147,7 @@ struct CTweakPlayer : ITweakPlayer
Value<float> x294_;
Value<float> x298_;
Value<float> x29c_;
Value<float> x2a0_;
Value<float> x2a0_orbitDistanceThreshold;
Value<float> x2a4_grappleSwingLength;
Value<float> x2a8_grappleSwingPeriod;
Value<float> x2ac_grapplePullSpeedMin;
@ -183,6 +183,7 @@ struct CTweakPlayer : ITweakPlayer
float GetFluidGravAccel() const { return xc8_fluidGravAccel; }
float GetHudLagAmount() const { return x138_hudLagAmount; }
float GetOrbitNormalDistance() const { return x180_orbitNormalDistance; }
float GetOrbitDistanceCompareSignificance() const { return x1a4_orbitDistanceCompareSignificance; }
uint32_t GetOrbitScreenBoxHalfExtentX(int zone) const { return x1a8_orbitScreenBoxHalfExtentX[zone]; }
uint32_t GetOrbitScreenBoxHalfExtentY(int zone) const { return x1b0_orbitScreenBoxHalfExtentY[zone]; }
uint32_t GetOrbitScreenBoxCenterX(int zone) const { return x1b8_orbitScreenBoxCenterX[zone]; }
@ -207,6 +208,7 @@ struct CTweakPlayer : ITweakPlayer
float GetX274() const { return x274_; }
float GetX278() const { return x278_; }
float GetPlayerBallHalfExtent() const { return x27c_playerBallHalfExtent; }
float GetOrbitDistanceThreshold() const { return x2a0_orbitDistanceThreshold; }
float GetGrappleSwingLength() const { return x2a4_grappleSwingLength; }
float GetGrappleSwingPeriod() const { return x2a8_grappleSwingPeriod; }
float GetGrapplePullSpeedMin() const { return x2ac_grapplePullSpeedMin; }

View File

@ -52,7 +52,7 @@ class CWorldState
std::shared_ptr<CWorldLayerState> x14_layerState;
public:
CWorldState(ResId id);
explicit CWorldState(ResId id);
CWorldState(CBitStreamReader& reader, ResId mlvlId, const CSaveWorld& saveWorld);
ResId GetWorldAssetId() const { return x0_mlvlId; }
void SetAreaId(TAreaId aid) { x4_areaId = aid; }

View File

@ -31,12 +31,16 @@ namespace urde
static const CMaterialFilter SolidMaterialFilter =
CMaterialFilter::MakeInclude(CMaterialList(EMaterialTypes::Solid));
static const CMaterialFilter TargetingFilter =
static const CMaterialFilter LineOfSightFilter =
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid},
{EMaterialTypes::ProjectilePassthrough,
EMaterialTypes::ScanPassthrough,
EMaterialTypes::Player});
static const CMaterialFilter OccluderFilter =
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid, EMaterialTypes::Occluder},
{EMaterialTypes::ProjectilePassthrough, EMaterialTypes::ScanPassthrough, EMaterialTypes::Player});
static CModelData MakePlayerAnimRes(ResId resId, const zeus::CVector3f& scale)
{
return {CAnimRes(resId, 0, scale, 0, true), 1};
@ -2037,7 +2041,7 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr)
{
CRayCastResult result =
mgr.RayStaticIntersection(eyePosition, playerToPoint.normalized(), playerToPoint.magnitude(),
TargetingFilter);
LineOfSightFilter);
if (result.IsInvalid())
{
HolsterGun(mgr);
@ -2170,7 +2174,7 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr)
{
CRayCastResult result =
mgr.RayStaticIntersection(eyePos, playerToPoint.normalized(), playerToPoint.magnitude(),
TargetingFilter);
LineOfSightFilter);
if (result.IsValid())
{
BreakGrapple(EPlayerOrbitRequest::Twelve, mgr);
@ -2442,12 +2446,189 @@ void CPlayer::UpdateOrbitableObjects(CStateManager& mgr)
FindOrbitableObjects(nearList, x364_offScreenOrbitObjects, x330_orbitZone, x334_orbitType, mgr, false);
}
TUniqueId CPlayer::FindBestOrbitableObject(const std::vector<TUniqueId>&, EPlayerZoneInfo, CStateManager& mgr) const
TUniqueId CPlayer::FindBestOrbitableObject(const std::vector<TUniqueId>& ids,
EPlayerZoneInfo info, CStateManager& mgr) const
{
zeus::CVector3f eyePos = GetEyePosition();
zeus::CVector3f lookDir = x34_transform.basis[1].normalized();
/* TODO: Finish */
return {};
float minEyeToOrbitMag = 10000.f;
float minPosInBoxMagSq = 10000.f;
TUniqueId bestId = kInvalidUniqueId;
int vpWidthHalf = g_Viewport.x8_width / 2;
int vpHeightHalf = g_Viewport.xc_height / 2;
float boxLeft = (g_tweakPlayer->GetEnemyScreenBoxCenterX(int(info)) *
g_Viewport.x8_width / 640 - vpWidthHalf) / vpWidthHalf;
float boxTop = (g_tweakPlayer->GetEnemyScreenBoxCenterY(int(info)) *
g_Viewport.xc_height / 448 - vpHeightHalf) / vpHeightHalf;
CFirstPersonCamera* fpCam = mgr.GetCameraManager()->GetFirstPersonCamera();
for (TUniqueId id : ids)
{
if (TCastToPtr<CActor> act = mgr.ObjectById(id))
{
zeus::CVector3f orbitPos = act->GetOrbitPosition(mgr);
zeus::CVector3f eyeToOrbit = orbitPos - eyePos;
float eyeToOrbitMag = eyeToOrbit.magnitude();
zeus::CVector3f orbitPosScreen = fpCam->ConvertToScreenSpace(orbitPos);
if (orbitPosScreen.z >= 0.f)
{
if (x310_orbitTargetId != id)
{
if (TCastToPtr<CScriptGrapplePoint> point = act.GetPtr())
{
if (x310_orbitTargetId != point->GetUniqueId())
{
if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::GrappleBeam) &&
eyeToOrbitMag < minEyeToOrbitMag &&
eyeToOrbitMag < g_tweakPlayer->GetOrbitDistanceThreshold())
{
rstl::reserved_vector<TUniqueId, 1024> nearList;
TUniqueId intersectId = kInvalidUniqueId;
eyeToOrbit.normalize();
mgr.BuildNearList(nearList, eyePos, eyeToOrbit, eyeToOrbitMag,
OccluderFilter, act.GetPtr());
eyeToOrbit.normalize();
CRayCastResult result =
mgr.RayWorldIntersection(intersectId, eyePos, eyeToOrbit, eyeToOrbitMag,
LineOfSightFilter, nearList);
if (result.IsInvalid())
{
if (point->GetGrappleParameters().GetLockSwingTurn())
{
zeus::CVector3f pointToPlayer =
GetTranslation() - point->GetTranslation();
if (pointToPlayer.canBeNormalized())
{
pointToPlayer.z = 0.f;
if (std::fabs(point->GetTransform().basis[1].normalized().
dot(pointToPlayer.normalized())) <= M_SQRT1_2F)
continue;
}
}
bestId = act->GetUniqueId();
float posInBoxLeft = orbitPosScreen.x - boxLeft;
float posInBoxTop = orbitPosScreen.y - boxTop;
minEyeToOrbitMag = eyeToOrbitMag;
minPosInBoxMagSq = posInBoxLeft * posInBoxLeft + posInBoxTop * posInBoxTop;
}
}
continue;
}
}
if (minEyeToOrbitMag - eyeToOrbitMag > g_tweakPlayer->GetOrbitDistanceCompareSignificance() &&
mgr.GetPlayerState()->GetCurrentVisor() != CPlayerState::EPlayerVisor::Scan)
{
rstl::reserved_vector<TUniqueId, 1024> nearList;
TUniqueId bestId = kInvalidUniqueId;
eyeToOrbit.normalize();
mgr.BuildNearList(nearList, eyePos, eyeToOrbit, eyeToOrbitMag,
OccluderFilter, act.GetPtr());
for (auto it = nearList.begin() ; it != nearList.end() ;)
{
if (CEntity* obj = mgr.ObjectById(*it))
{
if (obj->GetAreaIdAlways() != kInvalidAreaId)
{
if (mgr.GetNextAreaId() != obj->GetAreaIdAlways())
{
const CGameArea* area = mgr.GetWorld()->GetAreaAlways(obj->GetAreaIdAlways());
CGameArea::EOcclusionState state =
area->IsPostConstructed() ? area->GetOcclusionState() :
CGameArea::EOcclusionState::Occluded;
if (state == CGameArea::EOcclusionState::Occluded)
{
it = nearList.erase(it);
continue;
}
}
}
else
{
it = nearList.erase(it);
continue;
}
}
++it;
}
eyeToOrbit.normalize();
CRayCastResult result =
mgr.RayWorldIntersection(bestId, eyePos, eyeToOrbit, eyeToOrbitMag,
LineOfSightFilter, nearList);
if (result.IsInvalid())
{
bestId = act->GetUniqueId();
float posInBoxLeft = orbitPosScreen.x - boxLeft;
float posInBoxTop = orbitPosScreen.y - boxTop;
minEyeToOrbitMag = eyeToOrbitMag;
minPosInBoxMagSq = posInBoxLeft * posInBoxLeft + posInBoxTop * posInBoxTop;
}
}
if (std::fabs(eyeToOrbitMag - minEyeToOrbitMag) <
g_tweakPlayer->GetOrbitDistanceCompareSignificance() ||
mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::Scan)
{
float posInBoxLeft = orbitPosScreen.x - boxLeft;
float posInBoxTop = orbitPosScreen.y - boxTop;
float posInBoxMagSq = posInBoxLeft * posInBoxLeft + posInBoxTop * posInBoxTop;
if (posInBoxMagSq < minPosInBoxMagSq)
{
rstl::reserved_vector<TUniqueId, 1024> nearList;
TUniqueId bestId = kInvalidUniqueId;
eyeToOrbit.normalize();
mgr.BuildNearList(nearList, eyePos, eyeToOrbit, eyeToOrbitMag,
OccluderFilter, act.GetPtr());
for (auto it = nearList.begin() ; it != nearList.end() ;)
{
if (CEntity* obj = mgr.ObjectById(*it))
{
if (obj->GetAreaIdAlways() != kInvalidAreaId)
{
if (mgr.GetNextAreaId() != obj->GetAreaIdAlways())
{
const CGameArea* area =
mgr.GetWorld()->GetAreaAlways(obj->GetAreaIdAlways());
CGameArea::EOcclusionState state =
area->IsPostConstructed() ? area->GetOcclusionState() :
CGameArea::EOcclusionState::Occluded;
if (state == CGameArea::EOcclusionState::Occluded)
{
it = nearList.erase(it);
continue;
}
}
}
else
{
it = nearList.erase(it);
continue;
}
}
++it;
}
eyeToOrbit.normalize();
CRayCastResult result =
mgr.RayWorldIntersection(bestId, eyePos, eyeToOrbit, eyeToOrbitMag,
LineOfSightFilter, nearList);
if (result.IsInvalid())
{
bestId = act->GetUniqueId();
minPosInBoxMagSq = posInBoxMagSq;
minEyeToOrbitMag = eyeToOrbitMag;
}
}
}
}
}
}
}
return bestId;
}
void CPlayer::FindOrbitableObjects(const rstl::reserved_vector<TUniqueId, 1024>& nearObjects,
@ -2482,13 +2663,15 @@ void CPlayer::FindOrbitableObjects(const rstl::reserved_vector<TUniqueId, 1024>&
pass = true;
}
if (pass && (!act->GetDoTargetDistanceTest() || (orbitPos - eyePos).magnitude() <= GetOrbitMaxTargetDistance(mgr)))
if (pass && (!act->GetDoTargetDistanceTest() ||
(orbitPos - eyePos).magnitude() <= GetOrbitMaxTargetDistance(mgr)))
listOut.push_back(id);
}
}
}
bool CPlayer::WithinOrbitScreenBox(const zeus::CVector3f& screenCoords, EPlayerZoneInfo zone, EPlayerZoneType type) const
bool CPlayer::WithinOrbitScreenBox(const zeus::CVector3f& screenCoords, EPlayerZoneInfo zone,
EPlayerZoneType type) const
{
if (screenCoords.z >= 1.f)
return false;

2
nod

@ -1 +1 @@
Subproject commit d597400f4a83f9bb759b1c1ce44517c2fe7f886d
Subproject commit 42ef3a7958b616eb606c43fbe0fc5fa443373358

@ -1 +1 @@
Subproject commit ea1f1f7b93352baf8b0142bc9458b6a0f512775e
Subproject commit cd448ae32819248448d04fa3ff050c2a82e1d190