@@ -83,6 +83,7 @@ void AHuman::Clear()
83
83
m_BGArmFlailScalar = 0 .7F ;
84
84
m_EquipHUDTimer.Reset ();
85
85
m_WalkAngle.fill (Matrix ());
86
+ m_FlailArms = 1 .0F ;
86
87
87
88
m_DeviceState = SCANNING;
88
89
m_SweepState = NOSWEEP;
@@ -179,6 +180,7 @@ int AHuman::Create(const AHuman &reference) {
179
180
m_JetAngleRange = reference.m_JetAngleRange ;
180
181
m_FGArmFlailScalar = reference.m_FGArmFlailScalar ;
181
182
m_BGArmFlailScalar = reference.m_BGArmFlailScalar ;
183
+ m_FlailArms = reference.m_FlailArms ;
182
184
183
185
m_pFGHandGroup = dynamic_cast <AtomGroup *>(reference.m_pFGHandGroup ->Clone ());
184
186
m_pFGHandGroup->SetOwner (this );
@@ -253,6 +255,8 @@ int AHuman::ReadProperty(const std::string_view &propName, Reader &reader) {
253
255
reader >> m_FGArmFlailScalar;
254
256
} else if (propName == " BGArmFlailScalar" ) {
255
257
reader >> m_BGArmFlailScalar;
258
+ } else if (propName == " FlailArms" ) {
259
+ reader >> m_FlailArms;
256
260
} else if (propName == " FGArm" ) {
257
261
SetFGArm (dynamic_cast <Arm *>(g_PresetMan.ReadReflectedPreset (reader)));
258
262
} else if (propName == " BGArm" ) {
@@ -352,6 +356,8 @@ int AHuman::Save(Writer &writer) const
352
356
writer << m_FGArmFlailScalar;
353
357
writer.NewProperty (" BGArmFlailScalar" );
354
358
writer << m_BGArmFlailScalar;
359
+ writer.NewProperty (" FlailArms" );
360
+ writer << m_FlailArms;
355
361
writer.NewProperty (" FGArm" );
356
362
writer << m_pFGArm;
357
363
writer.NewProperty (" BGArm" );
@@ -3181,6 +3187,7 @@ void AHuman::Update()
3181
3187
// Movement direction
3182
3188
3183
3189
bool isStill = m_Vel.GetMagnitude () + m_PrevVel.GetMagnitude () < 1 .0F ;
3190
+ bool aiming = m_Controller.IsState (AIM_SHARP);
3184
3191
3185
3192
// If the pie menu is on, try to preserve whatever move state we had before it going into effect.
3186
3193
if (!m_Controller.IsState (PIE_MENU_ACTIVE)) {
@@ -3211,7 +3218,7 @@ void AHuman::Update()
3211
3218
}
3212
3219
3213
3220
// Walk backwards if the aiming is already focused in the opposite direction of travel.
3214
- if (analogAim.GetMagnitude () != 0 || m_Controller. IsState (AIM_SHARP) ) {
3221
+ if (analogAim.GetMagnitude () != 0 || aiming ) {
3215
3222
m_Paths[FGROUND][m_MoveState].SetHFlip (m_Controller.IsState (MOVE_LEFT));
3216
3223
m_Paths[BGROUND][m_MoveState].SetHFlip (m_Controller.IsState (MOVE_LEFT));
3217
3224
} else if ((m_Controller.IsState (MOVE_RIGHT) && m_HFlipped) || (m_Controller.IsState (MOVE_LEFT) && !m_HFlipped)) {
@@ -3300,14 +3307,14 @@ void AHuman::Update()
3300
3307
// Set the timer to a base number so we don't get a sluggish feeling at start.
3301
3308
if (m_AimState != AIMUP) { m_AimTmr.SetElapsedSimTimeMS (m_AimState == AIMSTILL ? 150 : 300 ); }
3302
3309
m_AimState = AIMUP;
3303
- m_AimAngle += m_Controller. IsState (AIM_SHARP) ? std::min (static_cast <float >(m_AimTmr.GetElapsedSimTimeMS ()) * 0 .00005F , 0 .05F ) : std::min (static_cast <float >(m_AimTmr.GetElapsedSimTimeMS ()) * 0 .00015F , 0 .15F ) * m_Controller.GetDigitalAimSpeed ();
3310
+ m_AimAngle += aiming ? std::min (static_cast <float >(m_AimTmr.GetElapsedSimTimeMS ()) * 0 .00005F , 0 .05F ) : std::min (static_cast <float >(m_AimTmr.GetElapsedSimTimeMS ()) * 0 .00015F , 0 .15F ) * m_Controller.GetDigitalAimSpeed ();
3304
3311
if (m_AimAngle > m_AimRange) { m_AimAngle = m_AimRange; }
3305
3312
3306
3313
} else if (m_Controller.IsState (AIM_DOWN) && m_Status != INACTIVE) {
3307
3314
// Set the timer to a base number so we don't get a sluggish feeling at start.
3308
3315
if (m_AimState != AIMDOWN) {m_AimTmr.SetElapsedSimTimeMS (m_AimState == AIMSTILL ? 150 : 300 ); }
3309
3316
m_AimState = AIMDOWN;
3310
- m_AimAngle -= m_Controller. IsState (AIM_SHARP) ? std::min (static_cast <float >(m_AimTmr.GetElapsedSimTimeMS ()) * 0 .00005F , 0 .05F ) : std::min (static_cast <float >(m_AimTmr.GetElapsedSimTimeMS ()) * 0 .00015F , 0 .15F ) * m_Controller.GetDigitalAimSpeed ();
3317
+ m_AimAngle -= aiming ? std::min (static_cast <float >(m_AimTmr.GetElapsedSimTimeMS ()) * 0 .00005F , 0 .05F ) : std::min (static_cast <float >(m_AimTmr.GetElapsedSimTimeMS ()) * 0 .00015F , 0 .15F ) * m_Controller.GetDigitalAimSpeed ();
3311
3318
if (m_AimAngle < -m_AimRange) { m_AimAngle = -m_AimRange; }
3312
3319
3313
3320
} else if (analogAim.GetMagnitude () != 0 && m_Status != INACTIVE) {
@@ -3343,7 +3350,7 @@ void AHuman::Update()
3343
3350
3344
3351
// TODO: make the delay data driven by both the actor and the device!
3345
3352
//
3346
- if (m_Controller. IsState (AIM_SHARP) && m_Status == STABLE && (m_MoveState == STAND || m_MoveState == CROUCH || m_MoveState == NOMOVE || m_MoveState == WALK) && m_Vel.GetMagnitude () < 5 .0F && GetEquippedItem ()) {
3353
+ if (aiming && m_Status == STABLE && (m_MoveState == STAND || m_MoveState == CROUCH || m_MoveState == NOMOVE || m_MoveState == WALK) && m_Vel.GetMagnitude () < 5 .0F && GetEquippedItem ()) {
3347
3354
float aimMag = analogAim.GetMagnitude ();
3348
3355
3349
3356
// If aim sharp is being done digitally, then translate to full analog aim mag
@@ -3376,8 +3383,14 @@ void AHuman::Update()
3376
3383
3377
3384
ThrownDevice *pThrown = nullptr ;
3378
3385
if (m_pFGArm && m_Status != INACTIVE) {
3379
- // Force arm to idle by reaching toward a virtually inaccessible point.
3380
- m_pFGArm->ReachToward (Vector ());
3386
+ if (m_pBGLeg && m_MoveState == WALK && m_FlailArms > 0 ) {
3387
+ m_pFGArm->ReachToward (m_pFGArm->GetJointPos () + m_pFGArm->GetIdleOffset ().GetXFlipped (m_HFlipped).RadRotate (std::sin (m_pBGLeg->GetRotAngle () + c_HalfPI * GetFlipFactor ()) * m_FlailArms));
3388
+ } else if (m_pFGLeg && m_FlailArms > 0 ) {
3389
+ m_pFGArm->ReachToward (m_pFGArm->GetJointPos () + m_pFGArm->GetIdleOffset ().GetXFlipped (m_HFlipped).RadRotate (std::sin (m_pFGLeg->GetRotAngle () + c_HalfPI * GetFlipFactor ()) * m_FlailArms));
3390
+ } else {
3391
+ // Force arm to idle by reaching toward a virtually inaccessible point.
3392
+ m_pFGArm->ReachToward (Vector ());
3393
+ }
3381
3394
3382
3395
// Activate held device, if it's not a thrown device.
3383
3396
if (m_pFGArm->HoldsHeldDevice () && !m_pFGArm->HoldsThrownDevice ()) {
@@ -3392,22 +3405,23 @@ void AHuman::Update()
3392
3405
else if (m_pFGArm->GetHeldMO ()) {
3393
3406
pThrown = dynamic_cast <ThrownDevice *>(m_pFGArm->GetHeldMO ());
3394
3407
if (pThrown) {
3408
+ pThrown->SetSharpAim (aiming ? 1 .0F : 0 );
3395
3409
if (m_Controller.IsState (WEAPON_FIRE)) {
3396
3410
if (m_ArmsState != THROWING_PREP) {
3397
3411
m_ThrowTmr.Reset ();
3398
3412
if (!pThrown->ActivatesWhenReleased ()) { pThrown->Activate (); }
3399
3413
}
3400
3414
m_ArmsState = THROWING_PREP;
3401
- m_pFGArm->ReachToward (m_Pos + ( m_pFGArm->GetParentOffset () + pThrown->GetStartThrowOffset ().RadRotate (m_AimAngle + m_AngularVel * deltaTime)) .GetXFlipped (m_HFlipped) * m_Rotation );
3415
+ m_pFGArm->ReachToward (m_pFGArm->GetJointPos () + pThrown->GetStartThrowOffset ().RadRotate (m_AimAngle + m_AngularVel * deltaTime).GetXFlipped (m_HFlipped));
3402
3416
} else if (m_ArmsState == THROWING_PREP) {
3403
3417
m_ArmsState = THROWING_RELEASE;
3404
3418
// TODO: figure out how to properly use EndThrowOffset, since it doesn't play much a role for just one frame!
3405
- m_pFGArm->SetHandPos (m_Pos + ( m_pFGArm->GetParentOffset () + pThrown->GetEndThrowOffset ().RadRotate (adjustedAimAngle)) .GetXFlipped (m_HFlipped) * m_Rotation );
3419
+ m_pFGArm->SetHandPos (m_pFGArm->GetJointPos () + pThrown->GetEndThrowOffset ().RadRotate (adjustedAimAngle).GetXFlipped (m_HFlipped));
3406
3420
3407
3421
MovableObject *pMO = m_pFGArm->ReleaseHeldMO ();
3408
3422
3409
3423
if (pMO) {
3410
- pMO->SetPos (m_Pos + ( m_pFGArm->GetParentOffset () + Vector (m_pFGArm->GetMaxLength (), -m_pFGArm->GetMaxLength () * 0 .5F )). GetXFlipped (m_HFlipped). RadRotate (adjustedAimAngle) * m_Rotation );
3424
+ pMO->SetPos (m_pFGArm->GetJointPos () + Vector (m_pFGArm->GetMaxLength () * GetFlipFactor () , -m_pFGArm->GetMaxLength () * 0 .5F ). RadRotate (adjustedAimAngle));
3411
3425
float maxThrowVel = pThrown->GetMaxThrowVel ();
3412
3426
float minThrowVel = pThrown->GetMinThrowVel ();
3413
3427
if (maxThrowVel == 0 ) {
@@ -3416,8 +3430,8 @@ void AHuman::Update()
3416
3430
minThrowVel = maxThrowVel * 0 .2F ;
3417
3431
}
3418
3432
Vector tossVec (minThrowVel + (maxThrowVel - minThrowVel) * GetThrowProgress (), 0 .5F * RandomNormalNum ());
3419
- tossVec.RadRotate (m_AimAngle);
3420
- pMO->SetVel (tossVec.GetXFlipped (m_HFlipped) * m_Rotation );
3433
+ tossVec.RadRotate (m_AimAngle + m_AngularVel * deltaTime );
3434
+ pMO->SetVel (tossVec.GetXFlipped (m_HFlipped));
3421
3435
pMO->SetAngularVel (m_AngularVel + RandomNum (-5 .0F , 2 .5F ) * GetFlipFactor ());
3422
3436
pMO->SetRotAngle (adjustedAimAngle);
3423
3437
@@ -3436,11 +3450,14 @@ void AHuman::Update()
3436
3450
}
3437
3451
if (pThrown->ActivatesWhenReleased ()) { pThrown->Activate (); }
3438
3452
m_ThrowTmr.Reset ();
3453
+ } else {
3454
+ m_pFGArm->ReachToward (m_pFGArm->GetJointPos () + pThrown->GetStanceOffset ().RadRotate (adjustedAimAngle));
3439
3455
}
3440
3456
}
3441
3457
} else if (m_ArmsState == THROWING_RELEASE && m_ThrowTmr.GetElapsedSimTimeMS () > 100 ) {
3442
3458
m_pFGArm->SetHeldMO (SwapNextInventory ());
3443
3459
m_pFGArm->SetHandPos (m_Pos + m_HolsterOffset.GetXFlipped (m_HFlipped));
3460
+ EquipShieldInBGArm ();
3444
3461
m_ArmsState = WEAPON_READY;
3445
3462
} else if (m_ArmsState == THROWING_RELEASE) {
3446
3463
m_pFGArm->SetHandPos (m_Pos + (m_HolsterOffset + Vector (15 , -15 )).GetXFlipped (m_HFlipped));
@@ -3546,7 +3563,7 @@ void AHuman::Update()
3546
3563
// Try to detect a new item
3547
3564
if (m_pFGArm && m_Status == STABLE) {
3548
3565
reach += m_pFGArm->GetMaxLength ();
3549
- reachPoint = m_pFGArm->GetPos () + m_pFGArm-> GetJointOffset (). GetXFlipped (m_HFlipped). RadRotate (m_pFGArm-> GetRotAngle () );
3566
+ reachPoint = m_pFGArm->GetJointPos ( );
3550
3567
if (!m_pItemInReach) {
3551
3568
MOID itemMOID = g_SceneMan.CastMORay (reachPoint, Vector (reach * RandomNum (), 0 ).RadRotate (GetAimAngle (true ) + RandomNum (-c_HalfPI, 0 .0F ) * GetFlipFactor ()), m_MOID, Activity::NoTeam, g_MaterialGrass, true , 2 );
3552
3569
@@ -3867,23 +3884,31 @@ void AHuman::Update()
3867
3884
m_pBGArm->ReachToward (m_pBGHandGroup->GetLimbPos (m_HFlipped));
3868
3885
3869
3886
} else {
3870
- if (HeldDevice * heldDevice = dynamic_cast <HeldDevice *>(GetEquippedItem ())) {
3887
+ HeldDevice * heldDevice = dynamic_cast <HeldDevice *>(GetEquippedItem ());
3888
+ ThrownDevice * thrownDevice = dynamic_cast <ThrownDevice *>(heldDevice);
3889
+ if (thrownDevice && (m_ArmsState == THROWING_PREP || aiming)) {
3890
+ m_pBGArm->ReachToward (m_pBGArm->GetJointPos () + thrownDevice->GetEndThrowOffset ().RadRotate (m_AimAngle).GetXFlipped (m_HFlipped));
3891
+ } else if (heldDevice) {
3871
3892
if (GetEquippedBGItem () && !heldDevice->IsOneHanded ()) {
3872
3893
UnequipBGArm ();
3873
3894
} else {
3874
- m_pBGArm->Reach (m_pFGArm-> GetHeldDevice () ->GetSupportPos ());
3895
+ m_pBGArm->Reach (heldDevice ->GetSupportPos ());
3875
3896
if (m_pBGArm->DidReach ()) {
3876
- m_pFGArm-> GetHeldDevice () ->SetSupported (true );
3877
- m_pBGArm->SetRecoil (m_pFGArm-> GetHeldDevice ()-> GetRecoilForce (), m_pFGArm-> GetHeldDevice ()-> GetRecoilOffset (), m_pFGArm-> GetHeldDevice () ->IsRecoiled ());
3897
+ heldDevice ->SetSupported (true );
3898
+ m_pBGArm->SetRecoil (heldDevice-> GetRecoilForce (), heldDevice-> GetRecoilOffset (), heldDevice ->IsRecoiled ());
3878
3899
} else {
3879
3900
// BGArm did not reach to support the device. Count device as supported anyway, if crouching.
3880
- m_pFGArm-> GetHeldDevice () ->SetSupported (m_MoveState == CROUCH || m_ProneState == PRONE);
3901
+ heldDevice ->SetSupported (m_MoveState == CROUCH || m_ProneState == PRONE);
3881
3902
m_pBGArm->SetRecoil (Vector (), Vector (), false );
3882
3903
}
3883
3904
}
3905
+ } else if (m_pFGLeg && m_MoveState == WALK && m_FlailArms > 0 ) {
3906
+ m_pBGArm->ReachToward (m_pBGArm->GetJointPos () + m_pBGArm->GetIdleOffset ().GetXFlipped (m_HFlipped).RadRotate (std::sin (m_pFGLeg->GetRotAngle () + c_HalfPI * GetFlipFactor ()) * m_FlailArms));
3907
+ } else if (m_pBGLeg && m_FlailArms > 0 ) {
3908
+ m_pBGArm->ReachToward (m_pBGArm->GetJointPos () + m_pBGArm->GetIdleOffset ().GetXFlipped (m_HFlipped).RadRotate (std::sin (m_pBGLeg->GetRotAngle () + c_HalfPI * GetFlipFactor ()) * m_FlailArms));
3884
3909
} else {
3885
- // Use an unreachable position to force this arm to idle, so it wont bug out where the AtomGroup was left off
3886
- m_pBGArm->Reach (Vector ());
3910
+ // Force arm to idle by reaching toward a virtually inaccessible point.
3911
+ m_pBGArm->ReachToward (Vector ());
3887
3912
}
3888
3913
}
3889
3914
} else {
@@ -4011,8 +4036,8 @@ void AHuman::Update()
4011
4036
}
4012
4037
4013
4038
// Rotational balancing spring calc
4014
- if (m_Status == STABLE)
4015
- {
4039
+ if (m_Status == STABLE) {
4040
+
4016
4041
// If we're supposed to be laying down on the ground, make the spring pull the body that way until we reach that angle
4017
4042
if (m_ProneState != NOTPRONE)
4018
4043
{
@@ -4096,34 +4121,27 @@ void AHuman::Update()
4096
4121
// ////////////////////////////////////////////////////////////////////////////////////////
4097
4122
4098
4123
void AHuman::DrawThrowingReticle (BITMAP *targetBitmap, const Vector &targetPos, float progressScalar) const {
4099
- const int pointCount = 9 ;
4100
- Vector points[pointCount];
4101
- // Color colors[pointCount];
4124
+ const int pointCount = 9 ;
4125
+ Vector points[pointCount];
4102
4126
4103
4127
for (int index = 0 ; index < pointCount; index++) {
4104
4128
points[index].SetXY (static_cast <float >(index * 4 ), 0 .0F );
4105
- // colors[index].SetRGB(255 - index * 3, 225 - index * 20, index);
4106
4129
}
4130
+ Vector outOffset (m_pFGArm->GetMaxLength () * GetFlipFactor (), -m_pFGArm->GetMaxLength () * 0 .5F );
4107
4131
4108
- Vector outOffset (15 .0F * GetFlipFactor (), -5 .0F );
4109
-
4110
- acquire_bitmap (targetBitmap);
4111
-
4112
- for (int i = 0 ; i < pointCount * progressScalar; ++i) {
4113
- points[i].FlipX (m_HFlipped);
4114
- points[i] += outOffset;
4115
- points[i].RadRotate ((m_AimAngle * GetFlipFactor ()) + m_Rotation.GetRadAngle ());
4116
- points[i] += m_Pos;
4117
- if (m_pFGArm)
4118
- points[i] += m_pFGArm->GetParentOffset ();
4132
+ acquire_bitmap (targetBitmap);
4119
4133
4120
- // Put the flickering glows on the reticle dots, in absolute scene coordinates
4121
- g_PostProcessMan.RegisterGlowDotEffect (points[i], YellowDot, 55 + RandomNum (0 , 100 ));
4134
+ for (int i = 0 ; i < pointCount * progressScalar; ++i) {
4135
+ points[i].FlipX (m_HFlipped);
4136
+ points[i] += outOffset;
4137
+ points[i].RadRotate (m_AimAngle * GetFlipFactor () + m_AngularVel * g_TimerMan.GetDeltaTimeSecs ());
4138
+ points[i] += m_pFGArm->GetJointPos ();
4122
4139
4123
- putpixel (targetBitmap, points[i].GetFloorIntX () - targetPos.GetFloorIntX (), points[i].GetFloorIntY () - targetPos.GetFloorIntY (), g_YellowGlowColor);
4124
- }
4140
+ g_PostProcessMan.RegisterGlowDotEffect (points[i], YellowDot, RandomNum (63 , 127 ));
4141
+ putpixel (targetBitmap, points[i].GetFloorIntX () - targetPos.GetFloorIntX (), points[i].GetFloorIntY () - targetPos.GetFloorIntY (), g_YellowGlowColor);
4142
+ }
4125
4143
4126
- release_bitmap (targetBitmap);
4144
+ release_bitmap (targetBitmap);
4127
4145
}
4128
4146
4129
4147
// ////////////////////////////////////////////////////////////////////////////////////////
0 commit comments