Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
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
14
15 override bool IsRunning()
16 {
17 return true;
18 }
19
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
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;
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 {
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 {
179
180 }
181 }
182};
proto external Managed FindComponent(typename typeName)
Definition Math.c:13
override void Update(IEntity owner, float timeSlice)
SCR_RecoilCameraShakeParams GetParams(ChimeraCharacter character)