Finish CGrappleArm

This commit is contained in:
Jack Andersen 2017-09-03 16:22:46 -10:00
parent 91600c31bf
commit 640623f3ef
25 changed files with 1042 additions and 189 deletions

View File

@ -115,6 +115,10 @@ struct ITweakPlayer : ITweak
virtual uint32_t GetGrappleJumpMode() const=0;
virtual bool GetOrbitReleaseBreaksGrapple() const=0;
virtual bool GetInvertGrappleTurn() const=0;
virtual float GetGrappleBeamSpeed() const=0;
virtual float GetGrappleBeamXWaveAmplitude() const=0;
virtual float GetGrappleBeamZWaveAmplitude() const=0;
virtual float GetGrappleBeamAnglePhaseDelta() const=0;
virtual float GetHorizontalFreeLookAngleVel() const=0;
virtual float GetVerticalFreeLookAngleVel() const=0; // x134
virtual float GetOrbitCameraSpeed() const=0; // x184

View File

@ -369,7 +369,7 @@ void CTweakPlayer::read(athena::io::IStreamReader& __dna_reader)
x2a8_grappleSwingPeriod = __dna_reader.readFloatBig();
/* x2ac_grapplePullSpeedMin */
x2ac_grapplePullSpeedMin = __dna_reader.readFloatBig();
/* x2b0_ */
/* x2b0_grappleCameraSpeed */
x2b0_grappleCameraSpeed = __dna_reader.readFloatBig();
/* x2b4_maxGrappleLockedTurnAlignDistance */
x2b4_maxGrappleLockedTurnAlignDistance = __dna_reader.readFloatBig();
@ -391,14 +391,14 @@ void CTweakPlayer::read(athena::io::IStreamReader& __dna_reader)
x2d4_orbitReleaseBreaksGrapple = __dna_reader.readBool();
/* x2d5_invertGrappleTurn */
x2d5_invertGrappleTurn = __dna_reader.readBool();
/* x2d8_ */
x2d8_ = __dna_reader.readFloatBig();
/* x2dc_ */
x2dc_ = __dna_reader.readFloatBig();
/* x2e0_ */
x2e0_ = __dna_reader.readFloatBig();
/* x2e4_ */
x2e4_ = __dna_reader.readFloatBig();
/* x2d8_grappleBeamSpeed */
x2d8_grappleBeamSpeed = __dna_reader.readFloatBig();
/* x2dc_grappleBeamXWaveAmplitude */
x2dc_grappleBeamXWaveAmplitude = __dna_reader.readFloatBig();
/* x2e0_grappleBeamZWaveAmplitude */
x2e0_grappleBeamZWaveAmplitude = __dna_reader.readFloatBig();
/* x2e4_grappleBeamAnglePhaseDelta */
x2e4_grappleBeamAnglePhaseDelta = __dna_reader.readFloatBig();
/* x26c_playerHeight */
x26c_playerHeight = __dna_reader.readFloatBig();
/* x270_playerXYHalfExtent */
@ -809,7 +809,7 @@ void CTweakPlayer::write(athena::io::IStreamWriter& __dna_writer) const
__dna_writer.writeFloatBig(x2a8_grappleSwingPeriod);
/* x2ac_grapplePullSpeedMin */
__dna_writer.writeFloatBig(x2ac_grapplePullSpeedMin);
/* x2b0_ */
/* x2b0_grappleCameraSpeed */
__dna_writer.writeFloatBig(x2b0_grappleCameraSpeed);
/* x2b4_maxGrappleLockedTurnAlignDistance */
__dna_writer.writeFloatBig(x2b4_maxGrappleLockedTurnAlignDistance);
@ -831,14 +831,14 @@ void CTweakPlayer::write(athena::io::IStreamWriter& __dna_writer) const
__dna_writer.writeBool(x2d4_orbitReleaseBreaksGrapple);
/* x2d5_invertGrappleTurn */
__dna_writer.writeBool(x2d5_invertGrappleTurn);
/* x2d8_ */
__dna_writer.writeFloatBig(x2d8_);
/* x2dc_ */
__dna_writer.writeFloatBig(x2dc_);
/* x2e0_ */
__dna_writer.writeFloatBig(x2e0_);
/* x2e4_ */
__dna_writer.writeFloatBig(x2e4_);
/* x2d8_grappleBeamSpeed */
__dna_writer.writeFloatBig(x2d8_grappleBeamSpeed);
/* x2dc_grappleBeamXWaveAmplitude */
__dna_writer.writeFloatBig(x2dc_grappleBeamXWaveAmplitude);
/* x2e0_grappleBeamZWaveAmplitude */
__dna_writer.writeFloatBig(x2e0_grappleBeamZWaveAmplitude);
/* x2e4_grappleBeamAnglePhaseDelta */
__dna_writer.writeFloatBig(x2e4_grappleBeamAnglePhaseDelta);
/* x26c_playerHeight */
__dna_writer.writeFloatBig(x26c_playerHeight);
/* x270_playerXYHalfExtent */
@ -1324,8 +1324,8 @@ void CTweakPlayer::read(athena::io::YAMLDocReader& __dna_docin)
x2a8_grappleSwingPeriod = __dna_docin.readFloat("x2a8_grappleSwingPeriod");
/* x2ac_grapplePullSpeedMin */
x2ac_grapplePullSpeedMin = __dna_docin.readFloat("x2ac_grapplePullSpeedMin");
/* x2b0_ */
x2b0_grappleCameraSpeed = __dna_docin.readFloat("x2b0_");
/* x2b0_grappleCameraSpeed */
x2b0_grappleCameraSpeed = __dna_docin.readFloat("x2b0_grappleCameraSpeed");
/* x2b4_maxGrappleLockedTurnAlignDistance */
x2b4_maxGrappleLockedTurnAlignDistance = __dna_docin.readFloat("x2b4_maxGrappleLockedTurnAlignDistance");
/* x2b8_grapplePullSpeedProportion */
@ -1346,14 +1346,14 @@ void CTweakPlayer::read(athena::io::YAMLDocReader& __dna_docin)
x2d4_orbitReleaseBreaksGrapple = __dna_docin.readBool("x2d4_orbitReleaseBreaksGrapple");
/* x2d5_invertGrappleTurn */
x2d5_invertGrappleTurn = __dna_docin.readBool("x2d5_invertGrappleTurn");
/* x2d8_ */
x2d8_ = __dna_docin.readFloat("x2d8_");
/* x2dc_ */
x2dc_ = __dna_docin.readFloat("x2dc_");
/* x2e0_ */
x2e0_ = __dna_docin.readFloat("x2e0_");
/* x2e4_ */
x2e4_ = __dna_docin.readFloat("x2e4_");
/* x2d8_grappleBeamSpeed */
x2d8_grappleBeamSpeed = __dna_docin.readFloat("x2d8_grappleBeamSpeed");
/* x2dc_grappleBeamXWaveAmplitude */
x2dc_grappleBeamXWaveAmplitude = __dna_docin.readFloat("x2dc_grappleBeamXWaveAmplitude");
/* x2e0_grappleBeamZWaveAmplitude */
x2e0_grappleBeamZWaveAmplitude = __dna_docin.readFloat("x2e0_grappleBeamZWaveAmplitude");
/* x2e4_grappleBeamAnglePhaseDelta */
x2e4_grappleBeamAnglePhaseDelta = __dna_docin.readFloat("x2e4_grappleBeamAnglePhaseDelta");
/* x26c_playerHeight */
x26c_playerHeight = __dna_docin.readFloat("x26c_playerHeight");
/* x270_playerXYHalfExtent */
@ -1824,8 +1824,8 @@ void CTweakPlayer::write(athena::io::YAMLDocWriter& __dna_docout) const
__dna_docout.writeFloat("x2a8_grappleSwingPeriod", x2a8_grappleSwingPeriod);
/* x2ac_grapplePullSpeedMin */
__dna_docout.writeFloat("x2ac_grapplePullSpeedMin", x2ac_grapplePullSpeedMin);
/* x2b0_ */
__dna_docout.writeFloat("x2b0_", x2b0_grappleCameraSpeed);
/* x2b0_grappleCameraSpeed */
__dna_docout.writeFloat("x2b0_grappleCameraSpeed", x2b0_grappleCameraSpeed);
/* x2b4_maxGrappleLockedTurnAlignDistance */
__dna_docout.writeFloat("x2b4_maxGrappleLockedTurnAlignDistance", x2b4_maxGrappleLockedTurnAlignDistance);
/* x2b8_grapplePullSpeedProportion */
@ -1846,14 +1846,14 @@ void CTweakPlayer::write(athena::io::YAMLDocWriter& __dna_docout) const
__dna_docout.writeBool("x2d4_orbitReleaseBreaksGrapple", x2d4_orbitReleaseBreaksGrapple);
/* x2d5_invertGrappleTurn */
__dna_docout.writeBool("x2d5_invertGrappleTurn", x2d5_invertGrappleTurn);
/* x2d8_ */
__dna_docout.writeFloat("x2d8_", x2d8_);
/* x2dc_ */
__dna_docout.writeFloat("x2dc_", x2dc_);
/* x2e0_ */
__dna_docout.writeFloat("x2e0_", x2e0_);
/* x2e4_ */
__dna_docout.writeFloat("x2e4_", x2e4_);
/* x2d8_grappleBeamSpeed */
__dna_docout.writeFloat("x2d8_grappleBeamSpeed", x2d8_grappleBeamSpeed);
/* x2dc_grappleBeamXWaveAmplitude */
__dna_docout.writeFloat("x2dc_grappleBeamXWaveAmplitude", x2dc_grappleBeamXWaveAmplitude);
/* x2e0_grappleBeamZWaveAmplitude */
__dna_docout.writeFloat("x2e0_grappleBeamZWaveAmplitude", x2e0_grappleBeamZWaveAmplitude);
/* x2e4_grappleBeamAnglePhaseDelta */
__dna_docout.writeFloat("x2e4_grappleBeamAnglePhaseDelta", x2e4_grappleBeamAnglePhaseDelta);
/* x26c_playerHeight */
__dna_docout.writeFloat("x26c_playerHeight", x26c_playerHeight);
/* x270_playerXYHalfExtent */

View File

@ -162,10 +162,10 @@ struct CTweakPlayer final : ITweakPlayer
Value<atUint32> x2d0_grappleJumpMode;
Value<bool> x2d4_orbitReleaseBreaksGrapple;
Value<bool> x2d5_invertGrappleTurn;
Value<float> x2d8_;
Value<float> x2dc_;
Value<float> x2e0_;
Value<float> x2e4_;
Value<float> x2d8_grappleBeamSpeed;
Value<float> x2dc_grappleBeamXWaveAmplitude;
Value<float> x2e0_grappleBeamZWaveAmplitude;
Value<float> x2e4_grappleBeamAnglePhaseDelta;
Value<float> x2e8_;
Value<float> x2ec_;
Value<float> x2f0_;
@ -280,6 +280,10 @@ struct CTweakPlayer final : ITweakPlayer
uint32_t GetGrappleJumpMode() const { return x2d0_grappleJumpMode; }
bool GetOrbitReleaseBreaksGrapple() const { return x2d4_orbitReleaseBreaksGrapple; }
bool GetInvertGrappleTurn() const { return x2d5_invertGrappleTurn; }
float GetGrappleBeamSpeed() const { return x2d8_grappleBeamSpeed; }
float GetGrappleBeamXWaveAmplitude() const { return x2dc_grappleBeamXWaveAmplitude; }
float GetGrappleBeamZWaveAmplitude() const { return x2e0_grappleBeamZWaveAmplitude; }
float GetGrappleBeamAnglePhaseDelta() const { return x2e4_grappleBeamAnglePhaseDelta; }
float GetHorizontalFreeLookAngleVel() const { return x130_horizontalFreeLookAngleVel; }
float GetVerticalFreeLookAngleVel() const { return x134_verticalFreeLookAngleVel; }
float GetOrbitCameraSpeed() const { return x184_orbitCameraSpeed; }

View File

@ -75,8 +75,9 @@ public:
Max
};
enum class EPlayerSuit : u32
enum class EPlayerSuit : s32
{
Invalid = -1,
Power,
Gravity,
Varia,

View File

@ -86,6 +86,7 @@ class CAnimData
friend class CModelData;
friend class CActor;
friend class CPlayerGun;
friend class CGrappleArm;
public:
enum class EAnimDir
{

View File

@ -66,6 +66,7 @@ public:
void Update(float dt, CStateManager& mgr);
void GeneratePoints(const std::vector<std::pair<zeus::CVector3f, zeus::CVector3f>>& vn);
void Draw(const zeus::CTransform& xf) const;
bool IsRaining() const { return x48_25_raining; }
};
}

View File

@ -52,6 +52,10 @@ public:
g_PointGenFunc = func;
g_PointGenCtx = ctx;
}
static void ClearPointGeneratorFunc()
{
g_PointGenFunc = nullptr;
}
static FPointGenerator g_PointGenFunc;
static void* g_PointGenCtx;
};

View File

@ -39,4 +39,4 @@ public:
}
#endif // __URDE_CAABOXSHADER_HPP__
#endif // __URDE_CAABOXSHADER_HPP__

View File

@ -10,7 +10,9 @@ enum class ERumbleFxId
Seven = 7,
Eleven = 11,
Twelve = 12,
Fifteen = 15
Fourteen = 14,
Fifteen = 15,
Seventeen = 17
};
enum class ERumblePriority
{

View File

@ -171,13 +171,40 @@ public:
void DoElectricCreate(const std::vector<zeus::CVector3f>& offsets)
{
int curIdx = x158_curParticle;
u32 curIdx = x158_curParticle;
for (int i=0 ; i<x15c_swooshes.size() ; ++i)
{
curIdx = (curIdx + 1) % x15c_swooshes.size();
curIdx = u32((curIdx + 1) % x15c_swooshes.size());
x15c_swooshes[curIdx].xc_translation = offsets[i];
}
}
void DoGrappleWarmup()
{
for (int i=0 ; i<x15c_swooshes.size()-1 ; ++i)
{
x1d0_26_disableUpdate = true;
Update(0.0);
}
}
void DoGrappleUpdate(const zeus::CVector3f& beamGunPos, const zeus::CTransform& rotation, float anglePhase,
float xAmplitude, float zAmplitude, const zeus::CVector3f& swooshSegDelta)
{
float rot = x15c_swooshes.back().x30_irot;
zeus::CVector3f trans = beamGunPos;
for (int i=0 ; i<x15c_swooshes.size() ; ++i)
{
SSwooshData& data = x15c_swooshes[i];
zeus::CVector3f vec;
if (i > 0)
vec = rotation * zeus::CVector3f(std::cos(i + anglePhase) * xAmplitude, 0.f,
std::sin(float(i)) * zAmplitude);
data.xc_translation = trans + vec;
trans += swooshSegDelta;
std::swap(rot, data.x30_irot);
}
}
};
}

View File

@ -1,31 +1,160 @@
#include "CFidget.hpp"
#include "CStateManager.hpp"
#include "World/CPlayer.hpp"
namespace urde
{
CFidget::EState CFidget::Update(int fire, bool bobbing, bool inStrikeCooldown, float dt, CStateManager& mgr)
static float kMinorFidgetDelay = 20.f;
static float kMajorFidgetDelay = 20.f;
CFidget::EState CFidget::Update(int fireButtonStates, bool bobbing,
bool inStrikeCooldown, float dt, CStateManager& mgr)
{
return EState::Zero;
switch (x0_state)
{
case EState::NoFidget:
break;
case EState::MinorFidget:
return x34_24_loading ? EState::Loading : EState::StillMinorFidget;
case EState::MajorFidget:
return x34_24_loading ? EState::Loading : EState::StillMajorFidget;
case EState::HolsterBeam:
return x34_24_loading ? EState::Loading : EState::StillHolsterBeam;
default:
x0_state = EState::NoFidget;
break;
}
if (fireButtonStates != 0)
{
x14_timeSinceFire = 0.f;
x2c_holsterTimeSinceFire = 0.f;
}
else
{
if (x14_timeSinceFire < 6.f)
x14_timeSinceFire += dt;
if (x2c_holsterTimeSinceFire < x30_timeUntilHolster + 1.f)
x2c_holsterTimeSinceFire += dt;
}
if (inStrikeCooldown)
x18_timeSinceStrikeCooldown = 0.f;
else if (x18_timeSinceStrikeCooldown < 11.f)
x18_timeSinceStrikeCooldown += dt;
if (mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Unmorphed)
{
if (x1c_timeSinceUnmorph < 21.f)
x1c_timeSinceUnmorph += dt;
}
else
{
x1c_timeSinceUnmorph = 0.f;
}
if (bobbing)
x20_timeSinceBobbing = 0.f;
else if (x20_timeSinceBobbing < 21.f)
x20_timeSinceBobbing += dt;
u32 pendingTriggerBits = 0;
if (x0_state == EState::NoFidget)
{
if ((x10_delayTimerEnableBits & 0x1) != 0)
{
x24_minorDelayTimer += dt;
if (x24_minorDelayTimer > kMinorFidgetDelay)
{
pendingTriggerBits |= 0x1;
x24_minorDelayTimer = 0.f;
}
}
if ((x10_delayTimerEnableBits & 0x2) != 0)
{
x28_majorDelayTimer += dt;
if (x28_majorDelayTimer > kMajorFidgetDelay)
{
pendingTriggerBits |= 0x2;
x28_majorDelayTimer = 0.f;
}
}
}
if (x2c_holsterTimeSinceFire > x30_timeUntilHolster)
{
x0_state = EState::HolsterBeam;
}
else
{
if (x18_timeSinceStrikeCooldown > 10.f && x1c_timeSinceUnmorph > 20.f && x20_timeSinceBobbing > 20.f)
{
if ((pendingTriggerBits & 0x1) != 0)
x8_delayTriggerBits |= 0x1;
else if ((pendingTriggerBits & 0x2) != 0)
x8_delayTriggerBits |= 0x2;
}
if ((x8_delayTriggerBits & 0x3) == 0x3)
x0_state = (mgr.GetActiveRandom()->Next() % 100) >= 50 ? EState::MajorFidget : EState::MinorFidget;
else if ((x8_delayTriggerBits & 0x1) == 0x1)
x0_state = EState::MinorFidget;
else if ((x8_delayTriggerBits & 0x2) == 0x2)
x0_state = EState::MajorFidget;
else
x0_state = EState::NoFidget;
}
switch (x0_state)
{
case EState::MinorFidget:
x34_24_loading = true;
x10_delayTimerEnableBits = 2;
x8_delayTriggerBits &= ~0x1;
kMinorFidgetDelay = mgr.GetActiveRandom()->Range(20.f, 29.f);
x4_type = SamusGun::EFidgetType::Minor;
xc_animSet = mgr.GetActiveRandom()->Range(0, 4);
break;
case EState::MajorFidget:
x34_24_loading = true;
x10_delayTimerEnableBits = 1;
x8_delayTriggerBits &= ~0x2;
kMajorFidgetDelay = mgr.GetActiveRandom()->Range(20.f, 30.f);
x4_type = SamusGun::EFidgetType::Major;
xc_animSet = mgr.GetActiveRandom()->Range(0, 5);
break;
case EState::HolsterBeam:
x4_type = SamusGun::EFidgetType::Minor;
x34_24_loading = true;
xc_animSet = 0;
break;
default:
break;
}
return x0_state;
}
void CFidget::ResetMinor()
{
x0_state = EState::NoFidget;
}
void CFidget::ResetAll()
{
x0_state = EState::Zero;
x0_state = EState::NoFidget;
x4_type = SamusGun::EFidgetType::Invalid;
x18_ = 0.f;
x1c_ = 0.f;
x14_ = 0.f;
x24_ = 0.f;
x28_ = 0.f;
x2c_ = 0.f;
x8_ = 0;
xc_parm2 = -1;
x10_ = 3;
x18_timeSinceStrikeCooldown = 0.f;
x1c_timeSinceUnmorph = 0.f;
x14_timeSinceFire = 0.f;
x24_minorDelayTimer = 0.f;
x28_majorDelayTimer = 0.f;
x2c_holsterTimeSinceFire = 0.f;
x8_delayTriggerBits = 0;
xc_animSet = -1;
x10_delayTimerEnableBits = 3;
x34_24_loading = false;
}

View File

@ -13,35 +13,36 @@ class CFidget
public:
enum class EState
{
Zero,
One,
Two,
Three,
Four,
Five,
Six,
Seven
NoFidget,
MinorFidget,
MajorFidget,
HolsterBeam,
StillMinorFidget,
StillMajorFidget,
StillHolsterBeam,
Loading
};
private:
EState x0_state = EState::Zero;
EState x0_state = EState::NoFidget;
SamusGun::EFidgetType x4_type = SamusGun::EFidgetType::Invalid;
u32 x8_ = 0;
s32 xc_parm2 = -1;
u32 x10_ = 3;
float x14_ = 0.f;
float x18_ = 0.f;
float x1c_ = 0.f;
float x20_ = 0.f;
float x24_ = 0.f;
float x28_ = 0.f;
float x2c_ = 0.f;
float x30_ = 105.f;
u32 x8_delayTriggerBits = 0;
// 0: panel, 1: panel reset, 2: adjust nozzle, 3: panel buttons
s32 xc_animSet = -1;
u32 x10_delayTimerEnableBits = 3;
float x14_timeSinceFire = 0.f;
float x18_timeSinceStrikeCooldown = 0.f;
float x1c_timeSinceUnmorph = 0.f;
float x20_timeSinceBobbing = 0.f;
float x24_minorDelayTimer = 0.f;
float x28_majorDelayTimer = 0.f;
float x2c_holsterTimeSinceFire = 0.f;
float x30_timeUntilHolster = 105.f;
bool x34_24_loading = false;
public:
EState GetState() const { return x0_state; }
SamusGun::EFidgetType GetType() const { return x4_type; }
s32 GetParm2() const { return xc_parm2; }
EState Update(int fire, bool bobbing, bool inStrikeCooldown, float dt, CStateManager& mgr);
s32 GetAnimSet() const { return xc_animSet; }
EState Update(int fireButtonStates, bool bobbing, bool inStrikeCooldown, float dt, CStateManager& mgr);
void ResetMinor();
void ResetAll();
void DoneLoading() { x34_24_loading = false; }

View File

@ -11,15 +11,15 @@ bool CGSFidget::Update(CAnimData& data, float dt, CStateManager& mgr)
return !data.IsAnimTimeRemaining(0.001f, "Whole Body");
}
s32 CGSFidget::SetAnim(CAnimData& data, s32 type, s32 gunId, s32 parm2, CStateManager& mgr)
s32 CGSFidget::SetAnim(CAnimData& data, s32 type, s32 gunId, s32 animSet, CStateManager& mgr)
{
const CPASDatabase& pas = data.GetCharacterInfo().GetPASDatabase();
CPASAnimParmData parms(1, CPASAnimParm::FromEnum(type), CPASAnimParm::FromInt32(gunId),
CPASAnimParm::FromInt32(parm2));
CPASAnimParm::FromInt32(animSet));
auto anim = pas.FindBestAnimation(parms, *mgr.GetActiveRandom(), -1);
bool loop = pas.GetAnimState(1)->GetAnimParmData(anim.second, 3).GetBoolValue();
x14_gunId = gunId;
x18_parm2 = parm2;
x18_animSet = animSet;
if (anim.second != -1)
{
data.EnableLooping(loop);
@ -30,10 +30,10 @@ s32 CGSFidget::SetAnim(CAnimData& data, s32 type, s32 gunId, s32 parm2, CStateMa
return anim.second;
}
void CGSFidget::LoadAnimAsync(CAnimData& data, s32 type, s32 gunId, s32 parm2, CStateManager& mgr)
void CGSFidget::LoadAnimAsync(CAnimData& data, s32 type, s32 gunId, s32 animSet, CStateManager& mgr)
{
CPASAnimParmData parms(1, CPASAnimParm::FromEnum(type), CPASAnimParm::FromInt32(gunId),
CPASAnimParm::FromInt32(parm2));
CPASAnimParm::FromInt32(animSet));
auto anim = data.GetCharacterInfo().GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1);
if (anim.second != -1)
NWeaponTypes::get_token_vector(data, anim.second, x0_anims, true);

View File

@ -13,11 +13,11 @@ class CGSFidget
std::vector<CToken> x0_anims;
s32 x10_ = -1;
s32 x14_gunId = -1;
s32 x18_parm2 = -1;
s32 x18_animSet = -1;
public:
bool Update(CAnimData& data, float dt, CStateManager& mgr);
s32 SetAnim(CAnimData& data, s32 type, s32 gunId, s32 parm2, CStateManager& mgr);
void LoadAnimAsync(CAnimData& data, s32 type, s32 gunId, s32 parm2, CStateManager& mgr);
s32 SetAnim(CAnimData& data, s32 type, s32 gunId, s32 animSet, CStateManager& mgr);
void LoadAnimAsync(CAnimData& data, s32 type, s32 gunId, s32 animSet, CStateManager& mgr);
void UnLoadAnim();
bool IsAnimLoaded() const;
};

View File

@ -1,95 +1,694 @@
#include "Particle/CElementGen.hpp"
#include "CDependencyGroup.hpp"
#include "CGrappleArm.hpp"
#include "GameGlobalObjects.hpp"
#include "CSimplePool.hpp"
#include "World/CPlayer.hpp"
#include "TCastTo.hpp"
#include "Camera/CGameCamera.hpp"
#include "Graphics/CSkinnedModel.hpp"
#include "Graphics/CVertexMorphEffect.hpp"
namespace urde
{
CGrappleArm::CGrappleArm(const zeus::CVector3f& vec)
float CGrappleArm::g_GrappleBeamAnglePhaseDelta = 0.875f;
float CGrappleArm::g_GrappleBeamXWaveAmplitude = 0.25f;
float CGrappleArm::g_GrappleBeamZWaveAmplitude = 0.125f;
float CGrappleArm::g_GrappleBeamSpeed = 5.f;
CGrappleArm::CGrappleArm(const zeus::CVector3f& scale)
: x0_grappleArmModel(CAnimRes(g_tweakGunRes->x8_grappleArm, 0, scale, 41, false)),
xa0_grappleGearModel(CStaticRes(NWeaponTypes::get_asset_id_from_name("GrappleGear"), scale)),
xec_grapNoz1Model(CStaticRes(NWeaponTypes::get_asset_id_from_name("GrapNoz1"), scale)),
x138_grapNoz2Model(CStaticRes(NWeaponTypes::get_asset_id_from_name("GrapNoz2"), scale)),
x184_grappleArm(g_SimplePool->GetObj(SObjectTag{FOURCC('ANCS'), g_tweakGunRes->x8_grappleArm})),
x31c_scale(scale),
x354_grappleSegmentDesc(g_SimplePool->GetObj(SObjectTag{FOURCC('PART'), g_tweakGunRes->xb4_grappleSegment})),
x360_grappleClawDesc(g_SimplePool->GetObj(SObjectTag{FOURCC('PART'), g_tweakGunRes->xb8_grappleClaw})),
x36c_grappleHitDesc(g_SimplePool->GetObj(SObjectTag{FOURCC('PART'), g_tweakGunRes->xbc_grappleHit})),
x378_grappleMuzzleDesc(g_SimplePool->GetObj(SObjectTag{FOURCC('PART'), g_tweakGunRes->xc0_grappleMuzzle})),
x384_grappleSwooshDesc(g_SimplePool->GetObj(SObjectTag{FOURCC('PART'), g_tweakGunRes->xc4_grappleSwoosh})),
x390_grappleSegmentGen(std::make_unique<CElementGen>(x354_grappleSegmentDesc,
CElementGen::EModelOrientationType::Normal,
CElementGen::EOptionalSystemFlags::One)),
x394_grappleClawGen(std::make_unique<CElementGen>(x360_grappleClawDesc,
CElementGen::EModelOrientationType::Normal,
CElementGen::EOptionalSystemFlags::One)),
x398_grappleHitGen(std::make_unique<CElementGen>(x36c_grappleHitDesc,
CElementGen::EModelOrientationType::Normal,
CElementGen::EOptionalSystemFlags::One)),
x39c_grappleMuzzleGen(std::make_unique<CElementGen>(x378_grappleMuzzleDesc,
CElementGen::EModelOrientationType::Normal,
CElementGen::EOptionalSystemFlags::One)),
x3a0_grappleSwooshGen(std::make_unique<CParticleSwoosh>(x384_grappleSwooshDesc, 0)),
x3a4_rainSplashGenerator(std::make_unique<CRainSplashGenerator>(scale, 20, 2, 0.f, 0.125f))
{
x0_grappleArmModel->SetSortThermal(true);
xa0_grappleGearModel.SetSortThermal(true);
xec_grapNoz1Model.SetSortThermal(true);
x138_grapNoz2Model.SetSortThermal(true);
g_GrappleBeamAnglePhaseDelta = g_tweakPlayer->GetGrappleBeamAnglePhaseDelta();
g_GrappleBeamXWaveAmplitude = g_tweakPlayer->GetGrappleBeamXWaveAmplitude();
g_GrappleBeamZWaveAmplitude = g_tweakPlayer->GetGrappleBeamZWaveAmplitude();
g_GrappleBeamSpeed = g_tweakPlayer->GetGrappleBeamSpeed();
x39c_grappleMuzzleGen->SetParticleEmission(false);
x390_grappleSegmentGen->SetParticleEmission(false);
x3a0_grappleSwooshGen->DoGrappleWarmup();
BuildSuitDependencyList();
LoadAnimations();
}
static const char* skDependencyNames[] =
{
"PowerSuit_DGRP",
"GravitySuit_DGRP",
"VariaSuit_DGRP",
"PhazonSuit_DGRP",
"FusionSuit_DGRP",
"FusionSuitG_DGRP",
"FusionSuitV_DGRP",
"FusionSuitP_DGRP",
};
void CGrappleArm::FillTokenVector(const std::vector<SObjectTag>& tags, std::vector<CToken>& objects)
{
objects.reserve(tags.size());
for (const SObjectTag& tag : tags)
objects.push_back(g_SimplePool->GetObj(tag));
}
void CGrappleArm::BuildSuitDependencyList()
{
x184_grappleArm.Lock();
for (const char* name : skDependencyNames)
{
TLockedToken<CDependencyGroup> dgrp = g_SimplePool->GetObj(name);
x19c_suitDeps.emplace_back();
std::vector<CToken>& depsOut = x19c_suitDeps.back();
FillTokenVector(dgrp->GetObjectTagVector(), depsOut);
}
}
void CGrappleArm::LoadAnimations()
{
NWeaponTypes::get_token_vector(*x0_grappleArmModel->GetAnimationData(), 0, 42, x18c_anims, true);
x0_grappleArmModel = std::experimental::nullopt;
}
void CGrappleArm::AsyncLoadSuit(CStateManager& mgr)
{
CPlayerState::EPlayerSuit suit = NWeaponTypes::get_current_suit(mgr);
if (suit == x3a8_loadedSuit)
return;
x0_grappleArmModel = std::experimental::nullopt;
x3b2_29_suitLoading = true;
if (x3a8_loadedSuit != CPlayerState::EPlayerSuit::Invalid)
{
NWeaponTypes::unlock_tokens(x19c_suitDeps[int(x3a8_loadedSuit)]);
x19c_suitDeps[int(x3a8_loadedSuit)].clear();
}
if (suit < CPlayerState::EPlayerSuit::Power || suit > CPlayerState::EPlayerSuit::FusionPhazon)
x3a8_loadedSuit = CPlayerState::EPlayerSuit::Power;
else
x3a8_loadedSuit = suit;
NWeaponTypes::lock_tokens(x19c_suitDeps[int(x3a8_loadedSuit)]);
}
void CGrappleArm::ResetAuxParams(bool resetGunController)
{
x3b2_24_active = false;
x3b2_27_armMoving = false;
x2e0_auxXf = zeus::CTransform::Identity();
if (resetGunController)
x328_gunController->Reset();
}
void CGrappleArm::DisconnectGrappleBeam()
{
x394_grappleClawGen->SetParticleEmission(false);
x3b2_25_beamActive = false;
GrappleBeamDisconnected();
}
void CGrappleArm::SetAnimState(EArmState state)
{
if (x334_animState == state)
return;
x0_grappleArmModel->AnimationData()->EnableLooping(false);
x3b2_28_isGrappling = true;
switch (state)
{
case EArmState::IntoGrapple:
{
ResetAuxParams(true);
CAnimPlaybackParms parms(0, -1, 1.f, true);
x0_grappleArmModel->AnimationData()->SetAnimation(parms, false);
x3b2_25_beamActive = false;
x3b2_24_active = true;
break;
}
case EArmState::IntoGrappleIdle:
{
CAnimPlaybackParms parms(1, -1, 1.f, true);
x0_grappleArmModel->AnimationData()->EnableLooping(true);
x0_grappleArmModel->AnimationData()->SetAnimation(parms, false);
break;
}
case EArmState::FireGrapple:
{
CAnimPlaybackParms parms(2, -1, 1.f, true);
x0_grappleArmModel->AnimationData()->SetAnimation(parms, false);
break;
}
case EArmState::ConnectGrapple:
{
CAnimPlaybackParms parms(3, -1, 1.f, true);
x0_grappleArmModel->AnimationData()->SetAnimation(parms, false);
break;
}
case EArmState::Connected:
{
CAnimPlaybackParms parms(3, -1, 1.f, true);
x0_grappleArmModel->AnimationData()->SetAnimation(parms, false);
break;
}
case EArmState::OutOfGrapple:
{
CAnimPlaybackParms parms(4, -1, 1.f, true);
x0_grappleArmModel->AnimationData()->SetAnimation(parms, false);
DisconnectGrappleBeam();
break;
}
case EArmState::Done:
x3b2_28_isGrappling = false;
break;
default:
break;
}
x334_animState = state;
}
void CGrappleArm::Activate(bool)
void CGrappleArm::Activate(bool intoGrapple)
{
SetAnimState(intoGrapple ? EArmState::IntoGrapple : EArmState::OutOfGrapple);
}
void CGrappleArm::GrappleBeamDisconnected()
{
if (x32c_grappleLoopSfx)
{
CSfxManager::SfxStop(x32c_grappleLoopSfx);
x32c_grappleLoopSfx.reset();
}
}
void CGrappleArm::GrappleBeamConnected()
{
if (!x32c_grappleLoopSfx)
x32c_grappleLoopSfx = NWeaponTypes::play_sfx(1527, false, true, -0.15f);
}
void CGrappleArm::RenderGrappleBeam(const CStateManager& mgr, const zeus::CVector3f& pos)
{
if (x3b2_24_active && !x3b2_29_suitLoading)
{
zeus::CTransform tmpXf = zeus::CTransform::Translate(pos) * x220_xf;
if (x3b2_25_beamActive)
{
if (x3b2_26_grappleHit)
x398_grappleHitGen->Render();
x394_grappleClawGen->Render();
x3a0_grappleSwooshGen->Render();
x390_grappleSegmentGen->Render();
zeus::CTransform backupViewMtx = CGraphics::g_ViewMatrix;
CGraphics::SetViewPointMatrix(tmpXf.inverse() * backupViewMtx);
CGraphics::SetModelMatrix(zeus::CTransform::Identity());
x39c_grappleMuzzleGen->Render();
CGraphics::SetViewPointMatrix(backupViewMtx);
}
}
}
void CGrappleArm::TouchModel(const CStateManager& mgr) const
{
if (x3b2_24_active && !x3b2_29_suitLoading)
{
x0_grappleArmModel->Touch(mgr, 0);
if (x50_grappleArmSkeletonModel)
x50_grappleArmSkeletonModel->Touch(mgr, 0);
if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::GrappleBeam))
{
xa0_grappleGearModel.Touch(mgr, 0);
xec_grapNoz1Model.Touch(mgr, 0);
x138_grapNoz2Model.Touch(mgr, 0);
}
}
}
void CGrappleArm::LoadSuitPoll()
{
if (NWeaponTypes::are_tokens_ready(x19c_suitDeps[int(x3a8_loadedSuit)]))
{
x0_grappleArmModel.emplace(CAnimRes(g_tweakGunRes->x8_grappleArm, 0, x31c_scale, 41, false));
x0_grappleArmModel->SetSortThermal(true);
x328_gunController = std::make_unique<CGunController>(*x0_grappleArmModel);
x3b2_29_suitLoading = false;
}
}
void CGrappleArm::BuildXRayModel()
{
x50_grappleArmSkeletonModel.emplace(CAnimRes(g_tweakGunRes->x8_grappleArm, 8, x31c_scale,
!x328_gunController ? 41 : x328_gunController->GetCurAnimId(), false));
x50_grappleArmSkeletonModel->SetSortThermal(true);
}
void CGrappleArm::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type)
{
switch (type)
{
case EUserEventType::Projectile:
if (x3b2_27_armMoving)
return;
x398_grappleHitGen = std::make_unique<CElementGen>(x36c_grappleHitDesc,
CElementGen::EModelOrientationType::Normal,
CElementGen::EOptionalSystemFlags::One);
x39c_grappleMuzzleGen = std::make_unique<CElementGen>(x378_grappleMuzzleDesc,
CElementGen::EModelOrientationType::Normal,
CElementGen::EOptionalSystemFlags::One);
x338_beamT = 0.f;
x33c_beamDist = 0.f;
x340_anglePhase = 0.f;
x344_xAmplitude = g_GrappleBeamXWaveAmplitude;
x348_zAmplitude = g_GrappleBeamZWaveAmplitude;
x398_grappleHitGen->SetParticleEmission(false);
x394_grappleClawGen->SetParticleEmission(true);
NWeaponTypes::play_sfx(1526, false, false, -0.15f);
mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::Fourteen, 1.f, ERumblePriority::Three);
break;
default:
break;
}
}
void CGrappleArm::DoUserAnimEvents(CStateManager& mgr)
{
zeus::CVector3f armToCam = mgr.GetCameraManager()->GetCurrentCamera(mgr)->GetTranslation() - x220_xf.origin;
const CAnimData& animData = *x0_grappleArmModel->GetAnimationData();
for (int i=0 ; i<animData.GetPassedSoundPOICount() ; ++i)
{
const CSoundPOINode& node = CAnimData::g_SoundPOINodes[i];
if (node.GetPoiType() != EPOIType::Sound ||
(node.GetCharacterIndex() != -1 && animData.x204_charIdx != node.GetCharacterIndex()))
continue;
NWeaponTypes::do_sound_event(x34c_animSfx, x3ac_pitchBend, false, node.GetSfxId(), node.GetWeight(),
node.GetFlags(), node.GetFalloff(), node.GetMaxDist(), 0.16f, 1.f, armToCam,
x220_xf.origin, mgr.GetPlayer().GetAreaIdAlways(), mgr);
}
for (int i=0 ; i<animData.GetPassedIntPOICount() ; ++i)
{
const CInt32POINode& node = CAnimData::g_Int32POINodes[i];
switch (node.GetPoiType())
{
case EPOIType::UserEvent:
DoUserAnimEvent(mgr, node, EUserEventType(node.GetValue()));
break;
case EPOIType::SoundInt32:
if (node.GetCharacterIndex() != -1 && animData.x204_charIdx != node.GetCharacterIndex())
break;
NWeaponTypes::do_sound_event(x34c_animSfx, x3ac_pitchBend, false, u32(node.GetValue()),
node.GetWeight(), node.GetFlags(), 0.1f, 150.f, 0.16f, 1.f, armToCam,
x220_xf.origin, mgr.GetPlayer().GetAreaIdAlways(), mgr);
break;
default:
break;
}
}
}
void CGrappleArm::UpdateArmMovement(float dt, CStateManager& mgr)
{
DoUserAnimEvents(mgr);
if (x328_gunController->Update(dt, mgr))
ResetAuxParams(false);
}
void CGrappleArm::UpdateGrappleBeamFx(const zeus::CVector3f& beamGunPos,
const zeus::CVector3f& beamAirPos, CStateManager& mgr)
{
x394_grappleClawGen->SetTranslation(beamAirPos);
x390_grappleSegmentGen->SetParticleEmission(true);
zeus::CVector3f segmentDelta = beamAirPos - beamGunPos;
zeus::CVector3f swooshSegmentDelta = segmentDelta * 0.02f;
int numSegments = int(2.f * segmentDelta.magnitude() + 1.f);
segmentDelta = (1.f / float(numSegments)) * segmentDelta;
zeus::CVector3f segmentPos = beamGunPos;
zeus::CTransform rotation = x220_xf.getRotation();
for (int i=0 ; i<numSegments ; ++i)
{
zeus::CVector3f vec;
if (i > 0)
vec = rotation * zeus::CVector3f(std::cos(i + x340_anglePhase) * x344_xAmplitude, 0.f,
std::sin(float(i)) * x348_zAmplitude);
x390_grappleSegmentGen->SetTranslation(vec * segmentPos);
x390_grappleSegmentGen->ForceParticleCreation(1);
segmentPos += segmentDelta;
}
x390_grappleSegmentGen->SetParticleEmission(false);
x3a0_grappleSwooshGen->DoGrappleUpdate(beamGunPos, rotation, x340_anglePhase, x344_xAmplitude,
x348_zAmplitude, swooshSegmentDelta);
}
bool CGrappleArm::UpdateGrappleBeam(float dt, const zeus::CTransform& beamLoc, CStateManager& mgr)
{
bool beamConnected = false;
if (TCastToConstPtr<CActor> act = mgr.GetObjectById(mgr.GetPlayer().GetOrbitTargetId()))
x310_grapplePointPos = act->GetTranslation();
else
x310_grapplePointPos = x220_xf.origin;
zeus::CVector3f beamGunPos = (x220_xf * beamLoc).origin;
zeus::CVector3f beamAirPos = beamGunPos * (1.f - x338_beamT) + x310_grapplePointPos * x338_beamT;
switch (x334_animState)
{
case EArmState::FireGrapple:
case EArmState::Three:
{
float gunToPointMag = (x310_grapplePointPos - beamGunPos).magnitude();
if (gunToPointMag > 0.f)
x338_beamT = x33c_beamDist / gunToPointMag;
else
x338_beamT = 1.f;
float speedMult =
mgr.GetPlayer().GetPlayerMovementState() != CPlayer::EPlayerMovementState::OnGround ? 2.f : 1.f;
x33c_beamDist += speedMult * (dt * g_GrappleBeamSpeed);
if (x338_beamT >= 1.f)
{
x338_beamT = 1.f;
beamConnected = true;
}
break;
}
case EArmState::ConnectGrapple:
{
float delta = 4.f * dt;
x344_xAmplitude -= delta;
x348_zAmplitude -= delta;
if (x344_xAmplitude < 0.f)
x344_xAmplitude = 0.f;
if (x348_zAmplitude < 0.f)
x348_zAmplitude = 0.f;
break;
}
default:
break;
}
if (x3b2_25_beamActive)
{
x340_anglePhase += g_GrappleBeamAnglePhaseDelta;
UpdateGrappleBeamFx(beamGunPos, beamAirPos, mgr);
x394_grappleClawGen->Update(dt);
x390_grappleSegmentGen->Update(dt);
}
return beamConnected;
}
void CGrappleArm::UpdateSwingAction(float grappleSwingT, float dt, CStateManager& mgr)
{
if (x3b2_29_suitLoading)
return;
if (x334_animState == EArmState::FireGrapple)
DoUserAnimEvents(mgr);
zeus::CTransform beamLocXf = x0_grappleArmModel->GetScaledLocatorTransform("LGBeam");
bool grappleConnected = UpdateGrappleBeam(dt, beamLocXf, mgr);
if ((grappleSwingT > 0.175f && grappleSwingT < 0.3f) ||
(grappleSwingT > 0.7f && grappleSwingT < 0.9f))
{
if (!CSfxManager::IsPlaying(x330_swooshSfx))
{
x330_swooshSfx = NWeaponTypes::play_sfx(1528, false, false, -0.15f);
if (x3b0_rumbleHandle != -1)
mgr.GetRumbleManager().StopRumble(x3b0_rumbleHandle);
x3b0_rumbleHandle = mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::Seventeen, 1.f, ERumblePriority::Three);
}
}
if (!x0_grappleArmModel->GetAnimationData()->IsAnimTimeRemaining(dt, "Whole Body"))
{
switch (x334_animState)
{
case EArmState::IntoGrapple:
case EArmState::Seven:
SetAnimState(EArmState::IntoGrappleIdle);
break;
case EArmState::FireGrapple:
if (grappleConnected)
{
SetAnimState(EArmState::ConnectGrapple);
x3b2_26_grappleHit = true;
x398_grappleHitGen->SetParticleEmission(true);
GrappleBeamConnected();
if (x3b0_rumbleHandle != -1)
mgr.GetRumbleManager().StopRumble(x3b0_rumbleHandle);
}
break;
case EArmState::ConnectGrapple:
if (x344_xAmplitude == 0.f)
SetAnimState(EArmState::Connected);
break;
case EArmState::OutOfGrapple:
if (x3b0_rumbleHandle != -1)
mgr.GetRumbleManager().StopRumble(x3b0_rumbleHandle);
SetAnimState(EArmState::Done);
x3b2_24_active = false;
break;
default:
break;
}
}
if (x3b2_25_beamActive)
{
x39c_grappleMuzzleGen->SetTranslation(beamLocXf.origin);
x39c_grappleMuzzleGen->Update(dt);
if (x3b2_26_grappleHit)
{
x3b2_26_grappleHit = !x398_grappleHitGen->IsSystemDeletable();
x398_grappleHitGen->SetTranslation(x310_grapplePointPos);
x398_grappleHitGen->Update(dt);
}
}
}
void CGrappleArm::Update(float grappleSwingT, float dt, CStateManager& mgr)
{
if (!(x3b2_24_active && !x3b2_29_suitLoading))
{
if (x3b2_29_suitLoading)
LoadSuitPoll();
return;
}
if (mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::XRay)
{
if (!x50_grappleArmSkeletonModel)
BuildXRayModel();
}
else
{
if (x50_grappleArmSkeletonModel)
x50_grappleArmSkeletonModel = std::experimental::nullopt;
}
float speed = 1.f;
if (!x3b2_27_armMoving)
speed = (mgr.GetPlayer().GetPlayerMovementState() != CPlayer::EPlayerMovementState::OnGround &&
x334_animState != EArmState::OutOfGrapple) ? 4.f : 1.f;
x0_grappleArmModel->AdvanceAnimation(speed * dt, mgr, kInvalidAreaId, true);
if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::GrappleBeam))
{
x250_grapLocatorXf = x0_grappleArmModel->GetScaledLocatorTransformDynamic("grapLocator_SDK", nullptr);
x280_grapNozLoc1Xf = x0_grappleArmModel->GetScaledLocatorTransform("gNozLoc1_SDK");
x2b0_grapNozLoc2Xf = x0_grappleArmModel->GetScaledLocatorTransform("gNozLoc1_SDK");
}
if (x3b2_27_armMoving)
UpdateArmMovement(dt, mgr);
else
UpdateSwingAction(grappleSwingT, dt, mgr);
if (x3a4_rainSplashGenerator)
x3a4_rainSplashGenerator->Update(dt, mgr);
}
void CGrappleArm::PreRender(const CStateManager& mgr, const zeus::CFrustum& frustum, const zeus::CVector3f& camPos)
{
if (x3b2_24_active && !x3b2_29_suitLoading)
{
x0_grappleArmModel->AnimationData()->PreRender();
if (x50_grappleArmSkeletonModel)
x50_grappleArmSkeletonModel->AnimationData()->PreRender();
}
}
void CGrappleArm::RenderXRayModel(const CStateManager& mgr, const zeus::CTransform& modelXf,
const CModelFlags& flags) const
{
CGraphics::SetModelMatrix(modelXf * zeus::CTransform::Scale(x0_grappleArmModel->GetScale()));
//CGraphics::DisableAllLights();
//g_Renderer->SetAmbientColor(zeus::CColor::skWhite);
CSkinnedModel& model =
const_cast<CSkinnedModel&>(*x50_grappleArmSkeletonModel->GetAnimationData()->GetModelData());
model.GetModelInst()->ActivateLights({CLight::BuildLocalAmbient({}, zeus::CColor::skWhite)});
const_cast<CGrappleArm*>(this)->x0_grappleArmModel->AnimationData()->Render(model, flags, {}, nullptr);
//g_Renderer->SetAmbientColor(zeus::CColor::skWhite);
//CGraphics::DisableAllLights();
}
void CGrappleArm::PointGenerator(void* ctx, const std::vector<std::pair<zeus::CVector3f, zeus::CVector3f>>& vn)
{
reinterpret_cast<CRainSplashGenerator*>(ctx)->GeneratePoints(vn);
}
void CGrappleArm::Render(const CStateManager& mgr, const zeus::CVector3f& pos,
const CModelFlags& flags, const CActorLights* lights) const
{
if (x3b2_24_active && !x3b2_29_suitLoading)
{
zeus::CTransform modelXf = zeus::CTransform::Translate(pos) * x220_xf * x2e0_auxXf;
if (x50_grappleArmSkeletonModel)
RenderXRayModel(mgr, modelXf, flags);
CModelFlags useFlags;
const CActorLights* useLights;
if (mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::XRay)
{
useFlags = CModelFlags(5, 0, 3, zeus::CColor(1.f, 0.25f));
useLights = nullptr;
}
else
{
useFlags = flags;
useLights = lights;
}
if (x3a4_rainSplashGenerator && x3a4_rainSplashGenerator->IsRaining())
CSkinnedModel::SetPointGeneratorFunc(x3a4_rainSplashGenerator.get(), PointGenerator);
x0_grappleArmModel->Render(mgr, modelXf, useLights, useFlags);
if (x3a4_rainSplashGenerator && x3a4_rainSplashGenerator->IsRaining())
{
CSkinnedModel::ClearPointGeneratorFunc();
x3a4_rainSplashGenerator->Draw(modelXf);
}
if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::GrappleBeam))
{
xa0_grappleGearModel.Render(mgr, modelXf * x250_grapLocatorXf, useLights, useFlags);
xec_grapNoz1Model.Render(mgr, modelXf * x280_grapNozLoc1Xf, useLights, useFlags);
x138_grapNoz2Model.Render(mgr, modelXf * x2b0_grapNozLoc2Xf, useLights, useFlags);
}
}
}
void CGrappleArm::AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&)
void CGrappleArm::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr)
{
if (msg == EScriptObjectMessage::Registered)
AsyncLoadSuit(mgr);
}
void CGrappleArm::EnterStruck(CStateManager& mgr, float angle, bool attack, bool b2)
void CGrappleArm::EnterStruck(CStateManager& mgr, float angle, bool bigStrike, bool notInFreeLook)
{
if (x3b2_29_suitLoading)
return;
if (x3b2_28_isGrappling)
{
DisconnectGrappleBeam();
x3b2_28_isGrappling = false;
}
if (!x3b2_27_armMoving)
{
x3b2_24_active = true;
x3b2_27_armMoving = true;
x334_animState = EArmState::GunControllerAnimation;
}
x328_gunController->EnterStruck(mgr, angle, bigStrike, notInFreeLook);
}
void CGrappleArm::EnterIdle(CStateManager& mgr)
{
if (x3b2_29_suitLoading)
return;
x328_gunController->EnterIdle(mgr);
}
void CGrappleArm::EnterFidget(CStateManager& mgr, SamusGun::EFidgetType type, s32 gunId, s32 parm2)
void CGrappleArm::EnterFidget(CStateManager& mgr, SamusGun::EFidgetType type, s32 gunId, s32 animSet)
{
if (x3b2_29_suitLoading)
return;
x3b2_24_active = true;
x3b2_27_armMoving = true;
x334_animState = EArmState::GunControllerAnimation;
x328_gunController->EnterFidget(mgr, s32(type), gunId, animSet);
}
void CGrappleArm::EnterFreeLook(s32 gunId, s32 setId, CStateManager& mgr)
{
if (x3b2_29_suitLoading)
return;
x3b2_24_active = true;
x3b2_27_armMoving = true;
x334_animState = EArmState::GunControllerAnimation;
x328_gunController->EnterFreeLook(mgr, gunId, setId);
}
void CGrappleArm::EnterComboFire(s32 gunId, CStateManager& mgr)
{
if (x3b2_29_suitLoading)
return;
x3b2_24_active = true;
x3b2_27_armMoving = true;
x334_animState = EArmState::GunControllerAnimation;
x328_gunController->EnterComboFire(mgr, gunId);
}
void CGrappleArm::ReturnToDefault(CStateManager& mgr, float f1, bool b1)
void CGrappleArm::ReturnToDefault(CStateManager& mgr, float dt, bool setState)
{
if (x3b2_29_suitLoading)
return;
x328_gunController->ReturnToDefault(mgr, dt, setState);
}
}

View File

@ -4,6 +4,7 @@
#include "RetroTypes.hpp"
#include "zeus/CVector3f.hpp"
#include "Character/CModelData.hpp"
#include "Character/CAnimCharacterSet.hpp"
#include "CStateManager.hpp"
#include "CGunController.hpp"
#include "CGunMotion.hpp"
@ -11,7 +12,7 @@
namespace urde
{
class CStateManager;
class CModelFlags;
struct CModelFlags;
class CActorLights;
class CGrappleArm
@ -19,30 +20,65 @@ class CGrappleArm
public:
enum class EArmState
{
Zero,
One,
Two,
IntoGrapple,
IntoGrappleIdle,
FireGrapple,
Three,
Four,
ConnectGrapple,
Five,
Six,
Connected,
Seven,
Eight,
Nine,
Ten
OutOfGrapple,
GunControllerAnimation,
Done
};
private:
CModelData x0_modelData;
std::experimental::optional<CModelData> x0_grappleArmModel;
std::experimental::optional<CModelData> x50_grappleArmSkeletonModel;
CModelData xa0_grappleGearModel;
CModelData xec_grapNoz1Model;
CModelData x138_grapNoz2Model;
TCachedToken<CAnimCharacterSet> x184_grappleArm;
std::vector<CToken> x18c_anims;
rstl::reserved_vector<std::vector<CToken>, 8> x19c_suitDeps;
zeus::CTransform x220_xf;
zeus::CTransform x250_grapLocatorXf;
zeus::CTransform x280_grapNozLoc1Xf;
zeus::CTransform x2b0_grapNozLoc2Xf;
zeus::CTransform x2e0_auxXf;
zeus::CVector3f x310_grapplePointPos;
zeus::CVector3f x31c_scale;
std::unique_ptr<CGunController> x328_gunController;
EArmState x334_animState;
CSfxHandle x32c_grappleLoopSfx;
CSfxHandle x330_swooshSfx;
EArmState x334_animState = EArmState::Done;
float x338_beamT = 0.f;
float x33c_beamDist = 0.f;
float x340_anglePhase = 0.f;
float x344_xAmplitude = 0.f;
float x348_zAmplitude = 0.f;
std::pair<u16, CSfxHandle> x34c_animSfx = {0xffff, {}};
TCachedToken<CGenDescription> x354_grappleSegmentDesc;
TCachedToken<CGenDescription> x360_grappleClawDesc;
TCachedToken<CGenDescription> x36c_grappleHitDesc;
TCachedToken<CGenDescription> x378_grappleMuzzleDesc;
TCachedToken<CSwooshDescription> x384_grappleSwooshDesc;
std::unique_ptr<CElementGen> x390_grappleSegmentGen;
std::unique_ptr<CElementGen> x394_grappleClawGen;
std::unique_ptr<CElementGen> x398_grappleHitGen;
std::unique_ptr<CElementGen> x39c_grappleMuzzleGen;
std::unique_ptr<CParticleSwoosh> x3a0_grappleSwooshGen;
std::unique_ptr<CRainSplashGenerator> x3a4_rainSplashGenerator;
CPlayerState::EPlayerSuit x3a8_loadedSuit = CPlayerState::EPlayerSuit::Invalid;
float x3ac_pitchBend = 0.f;
s16 x3b0_rumbleHandle = -1;
union
{
struct
{
bool x3b2_24_active : 1;
bool x3b2_25_beamActive : 1;
bool x3b2_26_grappleHit : 1;
bool x3b2_27_armMoving : 1;
bool x3b2_28_isGrappling : 1;
bool x3b2_29_suitLoading : 1;
@ -50,8 +86,30 @@ private:
u32 _dummy = 0;
};
static float g_GrappleBeamAnglePhaseDelta;
static float g_GrappleBeamXWaveAmplitude;
static float g_GrappleBeamZWaveAmplitude;
static float g_GrappleBeamSpeed;
void FillTokenVector(const std::vector<SObjectTag>& tags, std::vector<CToken>& objects);
void BuildSuitDependencyList();
void LoadAnimations();
void ResetAuxParams(bool resetGunController);
void DisconnectGrappleBeam();
void LoadSuitPoll();
void BuildXRayModel();
void DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type);
void DoUserAnimEvents(CStateManager& mgr);
void UpdateArmMovement(float dt, CStateManager& mgr);
void UpdateGrappleBeamFx(const zeus::CVector3f& beamGunPos, const zeus::CVector3f& beamAirPos, CStateManager& mgr);
bool UpdateGrappleBeam(float dt, const zeus::CTransform& beamLoc, CStateManager& mgr);
void UpdateSwingAction(float grappleSwingT, float dt, CStateManager& mgr);
void RenderXRayModel(const CStateManager& mgr, const zeus::CTransform& modelXf, const CModelFlags& flags) const;
static void PointGenerator(void* ctx, const std::vector<std::pair<zeus::CVector3f, zeus::CVector3f>>& vn);
public:
explicit CGrappleArm(const zeus::CVector3f& vec);
explicit CGrappleArm(const zeus::CVector3f& scale);
void AsyncLoadSuit(CStateManager& mgr);
void SetTransform(const zeus::CTransform& xf) { x220_xf = xf; }
const zeus::CTransform& GetTransform() const { return x220_xf; }
@ -73,12 +131,12 @@ public:
void Render(const CStateManager& mgr, const zeus::CVector3f& pos,
const CModelFlags& flags, const CActorLights* lights) const;
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
void EnterStruck(CStateManager& mgr, float angle, bool attack, bool b2);
void EnterStruck(CStateManager& mgr, float angle, bool bigStrike, bool notInFreeLook);
void EnterIdle(CStateManager& mgr);
void EnterFidget(CStateManager& mgr, SamusGun::EFidgetType type, s32 gunId, s32 parm2);
void EnterFidget(CStateManager& mgr, SamusGun::EFidgetType type, s32 gunId, s32 animSet);
void EnterFreeLook(s32 gunId, s32 setId, CStateManager& mgr);
void EnterComboFire(s32 gunId, CStateManager& mgr);
void ReturnToDefault(CStateManager& mgr, float f1, bool b1);
void ReturnToDefault(CStateManager& mgr, float dt, bool setState);
CGunController* GunController() { return x328_gunController.get(); }
};

View File

@ -6,14 +6,14 @@
namespace urde
{
void CGunController::LoadFidgetAnimAsync(CStateManager& mgr, s32 type, s32 gunId, s32 parm2)
void CGunController::LoadFidgetAnimAsync(CStateManager& mgr, s32 type, s32 gunId, s32 animSet)
{
x30_fidget.LoadAnimAsync(*x0_modelData.AnimationData(), type, gunId, parm2, mgr);
x30_fidget.LoadAnimAsync(*x0_modelData.AnimationData(), type, gunId, animSet, mgr);
}
void CGunController::EnterFidget(CStateManager& mgr, s32 type, s32 gunId, s32 parm2)
void CGunController::EnterFidget(CStateManager& mgr, s32 type, s32 gunId, s32 animSet)
{
x54_curAnimId = x30_fidget.SetAnim(*x0_modelData.AnimationData(), type, gunId, parm2, mgr);
x54_curAnimId = x30_fidget.SetAnim(*x0_modelData.AnimationData(), type, gunId, animSet, mgr);
x50_gunState = EGunState::Fidget;
}

View File

@ -40,8 +40,8 @@ public:
}
void UnLoadFidget() { x30_fidget.UnLoadAnim(); }
void LoadFidgetAnimAsync(CStateManager& mgr, s32 type, s32 gunId, s32 parm2);
void EnterFidget(CStateManager& mgr, s32 type, s32 gunId, s32 parm2);
void LoadFidgetAnimAsync(CStateManager& mgr, s32 type, s32 gunId, s32 animSet);
void EnterFidget(CStateManager& mgr, s32 type, s32 gunId, s32 animSet);
bool IsFidgetLoaded() const { return x30_fidget.IsAnimLoaded(); }
s32 GetFreeLookSetId() const { return x4_freeLook.GetSetId(); }
bool IsComboOver() const { return x1c_comboFire.IsComboOver(); }
@ -53,6 +53,7 @@ public:
void ReturnToDefault(CStateManager& mgr, float dt, bool setState);
void ReturnToBasePosition(CStateManager&, float);
void Reset();
s32 GetCurAnimId() const { return x54_curAnimId; }
};
}

View File

@ -24,8 +24,8 @@ enum class EAnimationState
enum class EFidgetType
{
Invalid = -1,
Zero,
One
Minor,
Major
};
}

View File

@ -127,8 +127,8 @@ public:
bool PlayPasAnim(SamusGun::EAnimationState state, CStateManager& mgr, float angle) { return false; }
void UnLoadFidget() {}
bool IsFidgetLoaded() const { return x100_gunController->IsFidgetLoaded(); }
void AsyncLoadFidget(CStateManager& mgr, SamusGun::EFidgetType type, s32 parm2)
{ x100_gunController->LoadFidgetAnimAsync(mgr, s32(type), s32(x200_beamId), parm2); }
void AsyncLoadFidget(CStateManager& mgr, SamusGun::EFidgetType type, s32 animSet)
{ x100_gunController->LoadFidgetAnimAsync(mgr, s32(type), s32(x200_beamId), animSet); }
void EnterFidget(CStateManager& mgr, SamusGun::EFidgetType type, s32 parm2)
{ x100_gunController->EnterFidget(mgr, s32(type), s32(x200_beamId), parm2); }
bool HasSolidModelData() const { return x10_solidModelData.operator bool(); }

View File

@ -530,7 +530,7 @@ void CPlayerGun::HandleBeamChange(const CFinalInput& input, CStateManager& mgr)
if (ExitMissile())
{
if (!CSfxManager::IsPlaying(x2e4_invalidSfx))
x2e4_invalidSfx = PlaySfx(1763, x834_27_underwater, false, 0.165f);
x2e4_invalidSfx = NWeaponTypes::play_sfx(1763, x834_27_underwater, false, 0.165f);
}
else
{
@ -588,15 +588,6 @@ void CPlayerGun::ResetBeamParams(CStateManager& mgr, const CPlayerState& playerS
x833_30_canShowAuxMuzzleEffect = true;
}
CSfxHandle CPlayerGun::PlaySfx(u16 sfx, bool underwater, bool looped, float pan)
{
CSfxHandle hnd = CSfxManager::SfxStart(sfx, 1.f, pan, true, 0x7f, looped, kInvalidAreaId);
CSfxManager::SfxSpan(hnd, 0.f);
if (underwater)
CSfxManager::PitchBend(hnd, -1.f);
return hnd;
}
static const u16 skFromMissileSound[] = { 1824, 1849, 1851, 1853 };
static const u16 skFromBeamSound[] = { 0, 1822, 1828, 1826 };
static const u16 skToMissileSound[] = { 1823, 1829, 1850, 1852 };
@ -628,7 +619,7 @@ void CPlayerGun::PlayAnim(NWeaponTypes::EGunAnimType type, bool loop)
}
if (sfx != 0xffff)
PlaySfx(sfx, x834_27_underwater, false, 0.165f);
NWeaponTypes::play_sfx(sfx, x834_27_underwater, false, 0.165f);
}
void CPlayerGun::CancelCharge(CStateManager& mgr, bool withEffect)
@ -776,9 +767,9 @@ void CPlayerGun::ReturnToRestPose()
void CPlayerGun::ResetIdle(CStateManager& mgr)
{
x550_camBob.SetState(CPlayerCameraBob::ECameraBobState::GunFireNoBob, mgr);
if (x3a4_fidget.GetState() != CFidget::EState::Zero)
if (x3a4_fidget.GetState() != CFidget::EState::NoFidget)
{
if (x3a4_fidget.GetState() == CFidget::EState::Seven)
if (x3a4_fidget.GetState() == CFidget::EState::Loading)
UnLoadFidget();
ReturnArmAndGunToDefault(mgr, true);
}
@ -1118,7 +1109,7 @@ void CPlayerGun::ProcessGunMorph(float dt, CStateManager& mgr)
x730_outgoingBeam = nullptr;
}
if (isUnmorphed)
PlaySfx(skIntoBeamSound[int(x310_currentBeam)], x834_27_underwater, false, 0.165f);
NWeaponTypes::play_sfx(skIntoBeamSound[int(x310_currentBeam)], x834_27_underwater, false, 0.165f);
x72c_currentBeam->SetRainSplashGenerator(x748_rainSplashGenerator.get());
x72c_currentBeam->EnableFx(true);
PlayAnim(NWeaponTypes::EGunAnimType::ToBeam, false);
@ -1149,7 +1140,7 @@ void CPlayerGun::SetPhazonBeamFeedback(bool active)
CSfxManager::SfxStop(x2e8_phazonBeamSfx);
x2e8_phazonBeamSfx.reset();
if (active)
x2e8_phazonBeamSfx = PlaySfx(3141, x834_27_underwater, false, 0.165f);
x2e8_phazonBeamSfx = NWeaponTypes::play_sfx(3141, x834_27_underwater, false, 0.165f);
}
void CPlayerGun::StartPhazonBeamTransition(bool active, CStateManager& mgr, CPlayerState& playerState)
@ -1284,7 +1275,7 @@ void CPlayerGun::UpdateChargeState(float dt, CStateManager& mgr)
{
PlayAnim(NWeaponTypes::EGunAnimType::ChargeUp, false);
if (!x2e0_chargeSfx)
x2e0_chargeSfx = PlaySfx(skBeamChargeUpSound[int(x310_currentBeam)],
x2e0_chargeSfx = NWeaponTypes::play_sfx(skBeamChargeUpSound[int(x310_currentBeam)],
x834_27_underwater, true, 0.165f);
if (x830_chargeRumbleHandle == -1)
x830_chargeRumbleHandle = mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::Twelve, 1.f,
@ -1503,7 +1494,7 @@ void CPlayerGun::FireSecondary(float dt, CStateManager& mgr)
if (x835_25_inPhazonBeam || x318_comboAmmoIdx == 0 ||
!mgr.GetPlayerState()->HasPowerUp(skItemArr[x318_comboAmmoIdx]) || (x2f8_stateFlags & 0x4) != 0x4)
{
PlaySfx(1781, x834_27_underwater, false, 0.165f);
NWeaponTypes::play_sfx(1781, x834_27_underwater, false, 0.165f);
return;
}
@ -1551,7 +1542,7 @@ void CPlayerGun::FireSecondary(float dt, CStateManager& mgr)
}
else
{
PlaySfx(skItemEmptySound[x318_comboAmmoIdx], x834_27_underwater, false, 0.165f);
NWeaponTypes::play_sfx(skItemEmptySound[x318_comboAmmoIdx], x834_27_underwater, false, 0.165f);
}
}
@ -1599,13 +1590,13 @@ void CPlayerGun::ActivateCombo(CStateManager& mgr)
}
x72c_currentBeam->EnableCharge(true);
StopChargeSound(mgr);
PlaySfx(1762, x834_27_underwater, false, 0.165f);
NWeaponTypes::play_sfx(1762, x834_27_underwater, false, 0.165f);
x32c_chargePhase = EChargePhase::ComboXfer;
}
}
else
{
PlaySfx(1781, x834_27_underwater, false, 0.165f);
NWeaponTypes::play_sfx(1781, x834_27_underwater, false, 0.165f);
}
}
@ -1780,7 +1771,7 @@ void CPlayerGun::UpdateWeaponFire(float dt, const CPlayerState& playerState, CSt
else
{
if (!CSfxManager::IsPlaying(x2e4_invalidSfx))
x2e4_invalidSfx = PlaySfx(1781, x834_27_underwater, false, 0.165f);
x2e4_invalidSfx = NWeaponTypes::play_sfx(1781, x834_27_underwater, false, 0.165f);
else
x2e4_invalidSfx.reset();
}
@ -1788,7 +1779,7 @@ void CPlayerGun::UpdateWeaponFire(float dt, const CPlayerState& playerState, CSt
}
else
{
if (x3a4_fidget.GetState() == CFidget::EState::Zero)
if (x3a4_fidget.GetState() == CFidget::EState::NoFidget)
{
if ((x2f8_stateFlags & 0x10) == 0x10 && x744_auxWeapon->IsComboFxActive(mgr))
{
@ -1819,7 +1810,7 @@ void CPlayerGun::EnterFreeLook(CStateManager& mgr)
x73c_gunMotion->GetFreeLookSetId(), mgr);
}
void CPlayerGun::SetFidgetAnimBits(int parm2, bool beamOnly)
void CPlayerGun::SetFidgetAnimBits(int animSet, bool beamOnly)
{
x2fc_fidgetAnimBits = 0;
if (beamOnly)
@ -1830,14 +1821,14 @@ void CPlayerGun::SetFidgetAnimBits(int parm2, bool beamOnly)
switch (x3a4_fidget.GetType())
{
case SamusGun::EFidgetType::Zero:
case SamusGun::EFidgetType::Minor:
x2fc_fidgetAnimBits = 1;
if (parm2 != 1)
if (animSet != 1)
return;
x2fc_fidgetAnimBits |= 4;
break;
case SamusGun::EFidgetType::One:
if (parm2 >= 6 || parm2 < 4)
case SamusGun::EFidgetType::Major:
if (animSet >= 6 || animSet < 4)
x2fc_fidgetAnimBits = 2;
else
x2fc_fidgetAnimBits = 1;
@ -1850,21 +1841,21 @@ void CPlayerGun::SetFidgetAnimBits(int parm2, bool beamOnly)
void CPlayerGun::AsyncLoadFidget(CStateManager& mgr)
{
SetFidgetAnimBits(x3a4_fidget.GetParm2(), x3a4_fidget.GetState() == CFidget::EState::Three);
SetFidgetAnimBits(x3a4_fidget.GetAnimSet(), x3a4_fidget.GetState() == CFidget::EState::HolsterBeam);
if ((x2fc_fidgetAnimBits & 0x1) == 0x1)
x73c_gunMotion->GunController().LoadFidgetAnimAsync(mgr, s32(x3a4_fidget.GetType()),
s32(x310_currentBeam), x3a4_fidget.GetParm2());
s32(x310_currentBeam), x3a4_fidget.GetAnimSet());
if ((x2fc_fidgetAnimBits & 0x2) == 0x2)
{
x72c_currentBeam->AsyncLoadFidget(mgr, (x3a4_fidget.GetState() == CFidget::EState::Three ?
SamusGun::EFidgetType::Zero : x3a4_fidget.GetType()), x3a4_fidget.GetParm2());
x72c_currentBeam->AsyncLoadFidget(mgr, (x3a4_fidget.GetState() == CFidget::EState::HolsterBeam ?
SamusGun::EFidgetType::Minor : x3a4_fidget.GetType()), x3a4_fidget.GetAnimSet());
x832_31_inRestPose = false;
}
if ((x2fc_fidgetAnimBits & 0x4) == 0x4)
if (CGunController* gc = x740_grappleArm->GunController())
gc->LoadFidgetAnimAsync(mgr, s32(x3a4_fidget.GetType()),
x3a4_fidget.GetType() != SamusGun::EFidgetType::Zero ? s32(x310_currentBeam) : 0,
x3a4_fidget.GetParm2());
x3a4_fidget.GetType() != SamusGun::EFidgetType::Minor ? s32(x310_currentBeam) : 0,
x3a4_fidget.GetAnimSet());
}
bool CPlayerGun::IsFidgetLoaded() const
@ -1885,7 +1876,7 @@ void CPlayerGun::EnterFidget(CStateManager& mgr)
{
if ((x2fc_fidgetAnimBits & 0x1) == 0x1)
{
x73c_gunMotion->EnterFidget(mgr, x3a4_fidget.GetType(), x3a4_fidget.GetParm2());
x73c_gunMotion->EnterFidget(mgr, x3a4_fidget.GetType(), x3a4_fidget.GetAnimSet());
x834_25_gunMotionFidgeting = true;
}
else
@ -1894,12 +1885,12 @@ void CPlayerGun::EnterFidget(CStateManager& mgr)
}
if ((x2fc_fidgetAnimBits & 0x2) == 0x2)
x72c_currentBeam->EnterFidget(mgr, x3a4_fidget.GetType(), x3a4_fidget.GetParm2());
x72c_currentBeam->EnterFidget(mgr, x3a4_fidget.GetType(), x3a4_fidget.GetAnimSet());
if ((x2fc_fidgetAnimBits & 0x4) == 0x4)
x740_grappleArm->EnterFidget(mgr, x3a4_fidget.GetType(),
x3a4_fidget.GetType() != SamusGun::EFidgetType::Zero ? s32(x310_currentBeam) : 0,
x3a4_fidget.GetParm2());
x3a4_fidget.GetType() != SamusGun::EFidgetType::Minor ? s32(x310_currentBeam) : 0,
x3a4_fidget.GetAnimSet());
UnLoadFidget();
x3a4_fidget.DoneLoading();
@ -1909,7 +1900,7 @@ void CPlayerGun::UpdateGunIdle(bool inStrikeCooldown, float camBobT, float dt, C
{
CPlayer& player = mgr.GetPlayer();
if (player.IsInFreeLook() && !x832_29_lockedOn && !x740_grappleArm->IsGrappling() &&
x3a4_fidget.GetState() != CFidget::EState::Three &&
x3a4_fidget.GetState() != CFidget::EState::HolsterBeam &&
player.GetGunHolsterState() == CPlayer::EGunHolsterState::Drawn && !x834_30_inBigStrike)
{
if ((x2f8_stateFlags & 0x8) != 0x8)
@ -1999,7 +1990,7 @@ void CPlayerGun::UpdateGunIdle(bool inStrikeCooldown, float camBobT, float dt, C
{
switch (x3a4_fidget.Update(x2ec_lastFireButtonStates, camBobT > 0.01f, inStrikeCooldown, dt, mgr))
{
case CFidget::EState::Zero:
case CFidget::EState::NoFidget:
if (x324_idleState != EIdleState::Idle)
{
x73c_gunMotion->PlayPasAnim(SamusGun::EAnimationState::Idle, mgr, 0.f, false);
@ -2007,9 +1998,9 @@ void CPlayerGun::UpdateGunIdle(bool inStrikeCooldown, float camBobT, float dt, C
}
x550_camBob.SetState(CPlayerCameraBob::ECameraBobState::WalkNoBob, mgr);
break;
case CFidget::EState::One:
case CFidget::EState::Two:
case CFidget::EState::Three:
case CFidget::EState::MinorFidget:
case CFidget::EState::MajorFidget:
case CFidget::EState::HolsterBeam:
if (x324_idleState != EIdleState::NotIdle)
{
x73c_gunMotion->BasePosition(false);
@ -2017,12 +2008,12 @@ void CPlayerGun::UpdateGunIdle(bool inStrikeCooldown, float camBobT, float dt, C
}
AsyncLoadFidget(mgr);
break;
case CFidget::EState::Seven:
case CFidget::EState::Loading:
if (IsFidgetLoaded())
EnterFidget(mgr);
break;
case CFidget::EState::Four:
case CFidget::EState::Five:
case CFidget::EState::StillMinorFidget:
case CFidget::EState::StillMajorFidget:
x550_camBob.SetState(CPlayerCameraBob::ECameraBobState::Walk, mgr);
x833_24_isFidgeting = false;
x834_26_animPlaying = x834_25_gunMotionFidgeting ? x73c_gunMotion->IsAnimPlaying() :
@ -2432,7 +2423,7 @@ void CPlayerGun::RenderEnergyDrainEffects(const CStateManager& mgr) const
void CPlayerGun::DrawArm(const CStateManager& mgr, const zeus::CVector3f& pos, const CModelFlags& flags) const
{
const CPlayer& player = mgr.GetPlayer();
if (!x740_grappleArm->GetActive() || x740_grappleArm->GetAnimState() == CGrappleArm::EArmState::Ten)
if (!x740_grappleArm->GetActive() || x740_grappleArm->GetAnimState() == CGrappleArm::EArmState::Done)
return;
if (player.GetGrappleState() != CPlayer::EGrappleState::None ||

View File

@ -328,7 +328,6 @@ private:
void SetPhazonBeamMorph(bool intoPhazonBeam);
void Reset(CStateManager& mgr, bool b1);
void ResetBeamParams(CStateManager& mgr, const CPlayerState& playerState, bool playSelectionSfx);
CSfxHandle PlaySfx(u16 sfx, bool underwater, bool looped, float pan);
void PlayAnim(NWeaponTypes::EGunAnimType type, bool loop);
void CancelCharge(CStateManager& mgr, bool withEffect);
bool ExitMissile();
@ -360,7 +359,7 @@ private:
void ProcessNormalState(u32 releasedStates, u32 pressedStates, CStateManager& mgr, float dt);
void UpdateWeaponFire(float dt, const CPlayerState& playerState, CStateManager& mgr);
void EnterFreeLook(CStateManager& mgr);
void SetFidgetAnimBits(int parm2, bool beamOnly);
void SetFidgetAnimBits(int animSet, bool beamOnly);
void AsyncLoadFidget(CStateManager& mgr);
bool IsFidgetLoaded() const;
void EnterFidget(CStateManager& mgr);

View File

@ -61,7 +61,7 @@ bool are_tokens_ready(const std::vector<CToken>& anims)
return true;
}
void get_token_vector(CAnimData& animData, int begin, int end, std::vector<CToken>& tokensOut, bool preLock)
void get_token_vector(const CAnimData& animData, int begin, int end, std::vector<CToken>& tokensOut, bool preLock)
{
std::set<CPrimitive> prims;
for (int i=begin ; i<end ; ++i)
@ -72,7 +72,7 @@ void get_token_vector(CAnimData& animData, int begin, int end, std::vector<CToke
primitive_set_to_token_vector(animData, prims, tokensOut, preLock);
}
void get_token_vector(CAnimData& animData, int animIdx, std::vector<CToken>& tokensOut, bool preLock)
void get_token_vector(const CAnimData& animData, int animIdx, std::vector<CToken>& tokensOut, bool preLock)
{
std::set<CPrimitive> prims;
CAnimPlaybackParms parms(animIdx, -1, 1.f, true);
@ -158,5 +158,32 @@ void do_sound_event(std::pair<u16, CSfxHandle>& sfxHandle, float& pitch, bool do
}
}
CAssetId get_asset_id_from_name(const char* name)
{
const SObjectTag* tag = g_ResFactory->GetResourceIdByName(name);
if (!tag)
return {};
return tag->id;
}
CPlayerState::EPlayerSuit get_current_suit(const CStateManager& mgr)
{
CPlayerState::EPlayerSuit suit = mgr.GetPlayerState()->GetCurrentSuit();
if (suit < CPlayerState::EPlayerSuit::Power || suit > CPlayerState::EPlayerSuit::FusionGravity)
suit = CPlayerState::EPlayerSuit::Power;
if (suit == CPlayerState::EPlayerSuit::FusionPower)
suit = CPlayerState::EPlayerSuit(int(suit) + int(mgr.GetPlayerState()->GetCurrentSuitRaw()));
return suit;
}
CSfxHandle play_sfx(u16 sfx, bool underwater, bool looped, float pan)
{
CSfxHandle hnd = CSfxManager::SfxStart(sfx, 1.f, pan, true, 0x7f, looped, kInvalidAreaId);
CSfxManager::SfxSpan(hnd, 0.f);
if (underwater)
CSfxManager::PitchBend(hnd, -1.f);
return hnd;
}
}
}

View File

@ -5,6 +5,7 @@
#include "DataSpec/DNACommon/Tweaks/ITweakPlayerGun.hpp"
#include "Audio/CSfxManager.hpp"
#include <set>
#include <Runtime/CPlayerState.hpp>
namespace urde
{
@ -56,12 +57,15 @@ void primitive_set_to_token_vector(const CAnimData& animData, const std::set<CPr
void unlock_tokens(std::vector<CToken>& anims);
void lock_tokens(std::vector<CToken>& anims);
bool are_tokens_ready(const std::vector<CToken>& anims);
void get_token_vector(CAnimData& animData, int begin, int end, std::vector<CToken>& tokensOut, bool preLock);
void get_token_vector(CAnimData& animData, int animIdx, std::vector<CToken>& tokensOut, bool preLock);
void get_token_vector(const CAnimData& animData, int begin, int end, std::vector<CToken>& tokensOut, bool preLock);
void get_token_vector(const CAnimData& animData, int animIdx, std::vector<CToken>& tokensOut, bool preLock);
void do_sound_event(std::pair<u16, CSfxHandle>& sfxHandle, float& pitch, bool doPitchBend, u32 soundId,
float weight, u32 flags, float falloff, float maxDist, float minVol, float maxVol,
const zeus::CVector3f& posToCam, const zeus::CVector3f& pos, TAreaId aid,
CStateManager& mgr);
CAssetId get_asset_id_from_name(const char* name);
CPlayerState::EPlayerSuit get_current_suit(const CStateManager& mgr);
CSfxHandle play_sfx(u16 sfx, bool underwater, bool looped, float pan);
}

View File

@ -1310,7 +1310,7 @@ void CPlayer::RenderGun(const CStateManager& mgr, const zeus::CVector3f& pos) co
return;
if (x490_gun->GetGrappleArm().GetActive() &&
x490_gun->GetGrappleArm().GetAnimState() != CGrappleArm::EArmState::Ten)
x490_gun->GetGrappleArm().GetAnimState() != CGrappleArm::EArmState::Done)
x490_gun->GetGrappleArm().RenderGrappleBeam(mgr, pos);
if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::Scan &&
@ -3834,11 +3834,11 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr)
case 0:
switch (x490_gun->GetGrappleArm().GetAnimState())
{
case CGrappleArm::EArmState::One:
case CGrappleArm::EArmState::IntoGrappleIdle:
if (ControlMapper::GetDigitalInput(ControlMapper::ECommands::FireOrBomb, input))
x490_gun->GetGrappleArm().SetAnimState(CGrappleArm::EArmState::Two);
x490_gun->GetGrappleArm().SetAnimState(CGrappleArm::EArmState::FireGrapple);
break;
case CGrappleArm::EArmState::Six:
case CGrappleArm::EArmState::Connected:
BeginGrapple(playerToPoint, mgr);
break;
default:
@ -3850,10 +3850,10 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr)
{
switch (x490_gun->GetGrappleArm().GetAnimState())
{
case CGrappleArm::EArmState::One:
x490_gun->GetGrappleArm().SetAnimState(CGrappleArm::EArmState::Two);
case CGrappleArm::EArmState::IntoGrappleIdle:
x490_gun->GetGrappleArm().SetAnimState(CGrappleArm::EArmState::FireGrapple);
break;
case CGrappleArm::EArmState::Six:
case CGrappleArm::EArmState::Connected:
BeginGrapple(playerToPoint, mgr);
break;
default:
@ -3865,10 +3865,10 @@ void CPlayer::UpdateGrappleState(const CFinalInput& input, CStateManager& mgr)
case 2:
switch (x490_gun->GetGrappleArm().GetAnimState())
{
case CGrappleArm::EArmState::One:
x490_gun->GetGrappleArm().SetAnimState(CGrappleArm::EArmState::Two);
case CGrappleArm::EArmState::IntoGrappleIdle:
x490_gun->GetGrappleArm().SetAnimState(CGrappleArm::EArmState::FireGrapple);
break;
case CGrappleArm::EArmState::Six:
case CGrappleArm::EArmState::Connected:
BeginGrapple(playerToPoint, mgr);
break;
default:
@ -4022,7 +4022,7 @@ void CPlayer::BreakGrapple(EPlayerOrbitRequest req, CStateManager& mgr)
SetOrbitRequest(req, mgr);
x3b8_grappleState = EGrappleState::None;
AddMaterial(EMaterialTypes::GroundCollider, mgr);
x490_gun->GetGrappleArm().SetAnimState(CGrappleArm::EArmState::Eight);
x490_gun->GetGrappleArm().SetAnimState(CGrappleArm::EArmState::OutOfGrapple);
if (!InGrappleJumpCooldown() && x3b8_grappleState != EGrappleState::JumpOff)
DrawGun(mgr);
}