Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_RecoilCameraShakeProgress.c
Go to the documentation of this file.
1 
5 {
6  protected float m_fProgress;
7  protected float m_fVelocity;
8 
9 
10  protected float m_fImpulseTime;
11  protected float m_fLastImpulseTime;
12 
13  protected vector m_vImpulseAngular;
14 
15  override bool IsRunning()
16  {
17  return true;
18  }
19 
20  protected SCR_RecoilCameraShakeParams GetParams(ChimeraCharacter character)
21  {
22  BaseWeaponManagerComponent weaponManager = null;
23 
24  if (character.IsInVehicle())
25  {
26  CompartmentAccessComponent compartmentAccess = character.GetCompartmentAccessComponent();
27  // Fallback to default VehicleCamera behavior if getting out
28  if (!compartmentAccess || !compartmentAccess.IsInCompartment() || compartmentAccess.IsGettingOut() || compartmentAccess.IsGettingIn())
29  return null;
30 
31  BaseCompartmentSlot compartment = compartmentAccess.GetCompartment();
32  if (!compartment)
33  return null;
34 
35  TurretControllerComponent turretController = TurretControllerComponent.Cast(compartment.GetController());
36  if (!turretController)
37  return null;
38 
39  weaponManager = turretController.GetWeaponManager();
40  }
41  else
42  {
43  weaponManager = character.GetCharacterController().GetWeaponManagerComponent();
44  }
45 
46  if (!weaponManager)
47  return null;
48 
49  BaseWeaponComponent weapon = weaponManager.GetCurrentWeapon();
50  if (!weapon)
51  return null;
52 
53  IEntity weaponEntity = weapon.GetOwner();
54  if (!weaponEntity)
55  return null;
56 
57  InventoryItemComponent item = InventoryItemComponent.Cast(weaponEntity.FindComponent(InventoryItemComponent));
58  if (!item)
59  return null;
60 
61  return SCR_RecoilCameraShakeParams.Cast(item.FindAttribute(SCR_RecoilCameraShakeParams));
62  }
63 
64  override void Update(IEntity owner, float timeSlice)
65  {
66  ChimeraCharacter ownerCharacter = ChimeraCharacter.Cast(owner);
67  if (!ownerCharacter)
68  {
69  if (IsRunning())
70  Clear();
71 
72  return;
73  }
74 
75  // Recoil-driven shake is based on the translation of weapon
76  // in its model space, fetch the data
77  vector recoilTranslation;
78  if (ownerCharacter.IsInVehicle())
79  {
80  CompartmentAccessComponent compartmentAccess = ownerCharacter.GetCompartmentAccessComponent();
81  if (compartmentAccess && compartmentAccess.IsInCompartment() && !compartmentAccess.IsGettingOut() && !compartmentAccess.IsGettingIn())
82  {
83  BaseCompartmentSlot compartment = compartmentAccess.GetCompartment();
84  if (compartment)
85  {
86  TurretControllerComponent turretController = TurretControllerComponent.Cast(compartment.GetController());
87  if (turretController)
88  {
89  TurretComponent turretComponent = turretController.GetTurretComponent();
90  if(turretComponent)
91  recoilTranslation = turretComponent.GetCurrentRecoilTranslation();
92  }
93  }
94  }
95  }
96  else
97  {
98  AimingComponent aimingComponent = ownerCharacter.GetWeaponAimingComponent();
99  if (aimingComponent)
100  recoilTranslation = aimingComponent.GetCurrentRecoilTranslation();
101  }
102 
103 
104 
105  // These values seem to be good enough as defaults,
106  // but fetching it from prefab data of weapon (item) is of course preferable
107  float recoilTarget = 0.0;
108  float maxPercentage = 1.0;
109  float blendIn = 0.01;
110  float blendOut = 0.2;
111  float maxVelocity = 10.0;
112  float minRate = 0.1;
113  float minThreshold = 0.1;
114  float impulseStanceMagnitude = 1.0;
115  float continuousStanceMagnitude = 1.0;
116  SCR_RecoilCameraShakeParams params = GetParams(ownerCharacter);
117  if (params)
118  {
119  recoilTarget = params.m_fRecoilTarget;
120  maxPercentage = params.m_fMaximumPercentage;
121  blendIn = params.m_fBlendInTime;
122  blendOut = params.m_fBlendOutTime;
123  maxVelocity = params.m_fMaxVelocity;
124  minRate = params.m_fMinImpulseRate;
125  minThreshold = params.m_fMinImpulseThreshold;
126  float dynStance = ownerCharacter.GetCharacterController().GetDynamicStance();
127  impulseStanceMagnitude = params.GetStanceImpulseMagnitude(dynStance);
128  continuousStanceMagnitude = params.GetStanceMagnitude(dynStance);
129  }
130 
131  // Based on the target translation, we convert our recoil amount into a [0,1] range
132  float recoil01;
133  if (recoilTarget > 0.0) // prevent div by 0
134  recoil01 = Math.AbsFloat(recoilTranslation[2] / recoilTarget);
135 
136  // We scale the recoil value so it's not completely linear
137  // and we make sure that we do not overshoot desired percentage applied
138  float target = Math.Clamp(Math.Pow(recoil01, 2), 0.0, maxPercentage);
139  float smoothTime;
140  if (target >= m_fProgress)
141  smoothTime = blendIn;
142  else
143  smoothTime = blendOut;
144 
145  // This value is the immediate value [0,1] of continuous shake applied
146  m_fProgress = Math.SmoothCD(m_fProgress, target, m_fVelocity, smoothTime, maxVelocity, timeSlice);
147 
148  // When the change and time since last impulse is great enough, we can
149  // trigger a large impulse that does not change that often as the underlying shake
150  m_fImpulseTime += timeSlice;
151  if (m_fProgress - minThreshold > target && m_fImpulseTime > m_fLastImpulseTime + minRate)
152  {
153  m_fLastImpulseTime = m_fImpulseTime;
154  m_vImpulseAngular = vector.Zero;
155  if (params)
156  {
157  m_vImpulseAngular = params.GetRandomYawPitchRollImpulse();
158  }
159  }
160 
161  // Interpolate impulse towards zero, clearing it out
162  // if value is set previously, the impulse just goes in different direction,
163  // which is completely acceptable as shake is concerned
164  float impulseTime = Math.Clamp((m_fImpulseTime - m_fLastImpulseTime) * 0.25, 0, 1);
165  m_vImpulseAngular = vector.Lerp(m_vImpulseAngular, vector.Zero, impulseTime);
166 
167  if (params)
168  {
169  m_vTranslation = m_fProgress * continuousStanceMagnitude * params.GetRandomTranslation();
170  m_vRotation = m_fProgress * impulseStanceMagnitude * m_vImpulseAngular;
171  m_fFovScale = params.GetFovScale(m_fProgress);
172  }
173  else if (m_fProgress > 0.0)
174  {
175  m_vImpulseAngular = vector.Lerp(m_vImpulseAngular, vector.Zero, m_fProgress);
176  m_vTranslation = vector.Lerp(m_vTranslation, vector.Zero, m_fProgress);
177  m_vRotation = vector.Lerp(m_vRotation, vector.Zero, m_fProgress);
178  m_fFovScale = Math.Lerp(m_fFovScale, 1.0, m_fProgress);
179 
180  }
181  }
182 };
SCR_RecoilCameraShakeProgress
Definition: SCR_RecoilCameraShakeProgress.c:4
Clear
void Clear(GenericEntity entity)
Definition: SCR_GadgetManagerComponent.c:105
BaseWeaponComponent
Definition: BaseWeaponComponent.c:12
SCR_GenericCameraShakeProgress
Definition: SCR_GenericCameraShakeProgress.c:5
InventoryItemComponent
Definition: InventoryItemComponent.c:12
TurretControllerComponent
Definition: TurretControllerComponent.c:12
SCR_RecoilCameraShakeParams
Definition: SCR_RecoilCameraShakeParams.c:5
params
Configs ServerBrowser KickDialogs params
Definition: SCR_NotificationSenderComponent.c:24
m_fFovScale
protected float m_fFovScale
Definition: SCR_CameraShakeManagerComponent.c:11