Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_CompassComponent.c
Go to the documentation of this file.
1 //------------------------------------------------------------------------------------------------
4 {
5  SY183, // US
6  ADRIANOV // Soviet
7 }
8 
10 [EntityEditorProps(category: "GameScripted/Gadgets", description: "Compass", color: "0 0 255 255")]
11 class SCR_CompassComponentClass : SCR_GadgetComponentClass
12 {
13  [Attribute(defvalue: "0", UIWidgets.ComboBox, "Set compass type", "", ParamEnumArray.FromEnum(SCR_ECompassType), category: "Compass")]
14  int m_iCompassType;
15 
16  [Attribute(defvalue: "1", uiwidget: UIWidgets.CheckBox, desc: "Approximate time (in seconds) for the needle to reach a new direction", params: "0.1 10 0.1", category: "Compass")]
17  float m_fDirectionChangeTime;
18 
19  [Attribute(defvalue: "25", uiwidget: UIWidgets.Slider, desc: "Percentage overshoot of the needle when settling", params: "0 95 0.1", category: "Compass")]
20  float m_fDirectionOvershootPercentage;
21 
22  [Attribute(defvalue: "2", UIWidgets.CheckBox, desc: "Frequency (in hertz) of the vertical shaking of the needle", params: "0.1 5 0.1", category: "Compass")]
23  float m_fShakeFrequency;
24 
25  [Attribute(defvalue: "15", uiwidget: UIWidgets.Slider, desc: "Percentage overshoot the vertical needle shaking", params: "0 95 0.1", category: "Compass")]
26  float m_fShakeOvershootPercentage;
27 
28  [Attribute(defvalue: "3", UIWidgets.CheckBox, desc: "Maximum angle (in degrees) of the shaking", params: "0 15 0.1", category: "Compass")]
29  float m_fShakeMaximumAngle;
30 
31  [Attribute("0 0.3 0", UIWidgets.Coords, desc: "camera position when displayed in map UI mode", category: "Compass")]
32  vector m_vMapCameraPos;
33 
34  [Attribute("{72691366C26BD901}Prefabs/Items/Equipment/Compass/Compass_SY183_Map.et", desc: "Compass prefab used for display within 2D map", category: "Compass")]
35  ResourceName m_sMapResource;
36 
37  // signals
38  bool m_bSignalInit = false;
39  int m_iSignalNeedle = -1;
40  int m_iSignalShake = -1;
41  int m_iSignalInHand = -1;
42  int m_iSignalInMap = -1;
43  int m_iSignalClose = -1;
44 
45  //------------------------------------------------------------------------------------------------
47  void InitSignals(IEntity owner)
48  {
49  SignalsManagerComponent signalMgr = SignalsManagerComponent.Cast( owner.FindComponent( SignalsManagerComponent ) );
50  if (!signalMgr)
51  return;
52 
53  // cache signals
54  m_iSignalNeedle = signalMgr.FindSignal("Needle");
55  m_iSignalShake = signalMgr.FindSignal("Shake");
56  m_iSignalInHand = signalMgr.FindSignal("InHand");
57  m_iSignalInMap = signalMgr.FindSignal("InMap");
58  m_iSignalClose = signalMgr.FindSignal("Close");
59 
60  if (m_iSignalNeedle != -1 && m_iSignalShake != -1 && m_iSignalInHand != -1)
61  m_bSignalInit = true;
62  }
63 
64  //------------------------------------------------------------------------------------------------
65  // constructor
67  void SCR_CompassComponentClass(BaseContainer prefab)
68  {
69  }
70 }
71 
73 class SCR_CompassComponent : SCR_GadgetComponent
74 {
75  static const float E = 2.71828182845904;
76 
77  // Derived from m_fDirectionChangeTime and m_fDirectionOvershootPercentage:
78  protected float m_fNeedleAccelerationConstant = 0;
79  protected float m_fNeedleDragConstant = 0;
80 
81  // The current position and velocity:
82  protected float m_fNeedleAngle = 0;
83  protected float m_fNeedleVelocity = 0;
84 
85  // Derived from m_fShakeFrequency and m_fShakeOvershootPercentage:
86  protected float m_fShakeAccelerationConstant = 0;
87  protected float m_fShakeDragConstant = 0;
88 
89  // The current shake angle and velocity:
90  protected float m_fShakeAngle = 0;
91  protected float m_fShakeVelocity = 0;
92 
93  // The shake is induced by the rotation since the last frame:
94  protected vector m_vPreviousFrameAngles;
95 
96  // Various:
97  protected bool m_bIsInMapMode;
98 
99  protected SignalsManagerComponent m_SignalManager;
100  protected ref SCR_CompassComponentClass m_PrefabData;
101 
102  //------------------------------------------------------------------------------------------------
105  ResourceName GetMapPrefabResource()
106  {
107  return m_PrefabData.m_sMapResource;
108  }
109 
110  //------------------------------------------------------------------------------------------------
113  protected void UpdateNeedleDirection(float timeSlice)
114  {
115  vector angles = GetOwner().GetYawPitchRoll();
116  float northDirection = -angles[0];
117 
118  float magneticTorque = Math.Sin((northDirection - m_fNeedleAngle) * Math.DEG2RAD);
119 
120  float acceleration = magneticTorque * m_fNeedleAccelerationConstant;
121  float drag = m_fNeedleVelocity * m_fNeedleDragConstant;
122 
123  float cappedTimeSlice = Math.Min(timeSlice, 1);
124 
125  m_fNeedleVelocity += (acceleration - drag) * cappedTimeSlice;
126  m_fNeedleAngle += m_fNeedleVelocity * cappedTimeSlice;
127 
128  m_fNeedleAngle = SCR_Math.fmod(m_fNeedleAngle, 360);
129  if (m_fNeedleAngle > 180) m_fNeedleAngle -= 360;
130 
131  m_SignalManager.SetSignalValue(m_PrefabData.m_iSignalNeedle, m_fNeedleAngle);
132  }
133 
134  //------------------------------------------------------------------------------------------------
137  protected void UpdateNeedleShake(float timeSlice)
138  {
139  vector angles = GetOwner().GetYawPitchRoll();
140  vector deltaAngles = (m_vPreviousFrameAngles - angles);
141 
142  m_vPreviousFrameAngles = angles;
143 
144  float acceleration = -m_fShakeAngle * m_fShakeAccelerationConstant;
145  float drag = m_fShakeVelocity * m_fShakeDragConstant;
146 
147  float cappedTimeSlice = Math.Min(timeSlice, 1);
148 
149  m_fShakeVelocity += (acceleration - drag) * cappedTimeSlice;
150 
151  // The pitch change is added to the angle (as if the needle stayed still as the compass was
152  // rotated around the X axis) and yaw is added as shake when you spin around quickly:
153  m_fShakeAngle += m_fShakeVelocity * cappedTimeSlice + deltaAngles[0] + deltaAngles[1];
154 
155  // The needle hit the glass or base below it, and stopped:
156  if (m_fShakeAngle > m_PrefabData.m_fShakeMaximumAngle)
157  {
158  m_fShakeVelocity = 0;
159  m_fShakeAngle = m_PrefabData.m_fShakeMaximumAngle;
160  }
161 
162  if (m_fShakeAngle < -m_PrefabData.m_fShakeMaximumAngle)
163  {
164  m_fShakeVelocity = 0;
165  m_fShakeAngle = -m_PrefabData.m_fShakeMaximumAngle;
166  }
167 
168  m_SignalManager.SetSignalValue(m_PrefabData.m_iSignalShake, m_fShakeAngle);
169  }
170 
171  //------------------------------------------------------------------------------------------------
173  void Init2DMapCompass()
174  {
175  // Perturb the compass a bit:
176  m_fShakeAngle = m_PrefabData.m_fShakeMaximumAngle;
177  m_fNeedleVelocity = 5;
178 
179  // Initial set
180  vector angles = GetOwner().GetYawPitchRoll();
181  m_fNeedleAngle = -angles[0] + Math.RandomInt(-10, 10);
182  m_SignalManager.SetSignalValue(m_PrefabData.m_iSignalNeedle, m_fNeedleAngle);
183  }
184 
185  //------------------------------------------------------------------------------------------------
187  void DragMapCompass()
188  {
189  // Perturb the compass a bit:
190  m_fShakeAngle = m_PrefabData.m_fShakeMaximumAngle;
191  m_fNeedleVelocity = 5;
192  }
193 
194  //------------------------------------------------------------------------------------------------
196  void SetMapMode()
197  {
198  m_iMode = EGadgetMode.IN_HAND;
199  m_bActivated = true;
200  m_bIsInMapMode = true;
201 
202  UpdateCompassState();
203  }
204 
205  //------------------------------------------------------------------------------------------------
207  vector GetMapCamPosition()
208  {
209  return m_PrefabData.m_vMapCameraPos;
210  }
211 
212  //------------------------------------------------------------------------------------------------
214  protected void UpdateCompassState()
215  {
216  if (System.IsConsoleApp())
217  return;
218 
219  if (m_bActivated)
220  ActivateGadgetUpdate();
221  else
222  DeactivateGadgetUpdate();
223 
224  if (!m_PrefabData.m_bSignalInit)
225  m_PrefabData.InitSignals(GetOwner());
226 
227  // Map
228  if (m_bIsInMapMode)
229  {
230  m_SignalManager.SetSignalValue(m_PrefabData.m_iSignalInMap, 1);
231  m_SignalManager.SetSignalValue(m_PrefabData.m_iSignalInHand, 0);
232 
233  if (m_PrefabData.m_iCompassType == SCR_ECompassType.SY183)
234  m_SignalManager.SetSignalValue(m_PrefabData.m_iSignalClose, 0);
235  }
236  // Hand
237  else if (m_iMode != EGadgetMode.IN_SLOT)
238  {
239  m_SignalManager.SetSignalValue(m_PrefabData.m_iSignalInHand, 1);
240 
241  if (m_PrefabData.m_iCompassType == SCR_ECompassType.SY183)
242  m_SignalManager.SetSignalValue(m_PrefabData.m_iSignalClose, 0);
243  }
244  // Ground
245  else
246  {
247  m_SignalManager.SetSignalValue(m_PrefabData.m_iSignalInHand, 0);
248 
249  if (m_PrefabData.m_iCompassType == SCR_ECompassType.SY183)
250  m_SignalManager.SetSignalValue(m_PrefabData.m_iSignalClose, 1);
251  }
252  }
253 
254  //------------------------------------------------------------------------------------------------
257  protected float GetDampingRatio(float overshootPercentage)
258  {
259  float logOvershoot = Math.Log2(Math.Max(0.001, overshootPercentage / 100.0)) / Math.Log2(E);
260  float zeta = -logOvershoot / Math.Sqrt(Math.PI * Math.PI + logOvershoot * logOvershoot);
261 
262  return zeta;
263  }
264 
265  //------------------------------------------------------------------------------------------------
267  protected void CalculateConstants()
268  {
269  // Calculate the needle constants:
270  float zeta = GetDampingRatio(m_PrefabData.m_fDirectionOvershootPercentage);
271  float naturalFrequency = Math.PI / Math.Max(0.1, m_PrefabData.m_fDirectionChangeTime);
272 
273  m_fNeedleAccelerationConstant = naturalFrequency * naturalFrequency * Math.RAD2DEG;
274  m_fNeedleDragConstant = 2 * naturalFrequency * zeta;
275 
276  // Calculate the shake constants:
277  zeta = GetDampingRatio(m_PrefabData.m_fShakeOvershootPercentage);
278  naturalFrequency = m_PrefabData.m_fShakeFrequency;
279 
280  m_fShakeAccelerationConstant = naturalFrequency * naturalFrequency * Math.RAD2DEG;
281  m_fShakeDragConstant = 2 * naturalFrequency * zeta;
282  }
283 
284 
285  //------------------------------------------------------------------------------------------------
286  override void ModeSwitch(EGadgetMode mode, IEntity charOwner)
287  {
288  super.ModeSwitch(mode, charOwner);
289 
290  if (mode == EGadgetMode.IN_HAND)
291  {
292  m_bActivated = true;
293  UpdateCompassState();
294  }
295  }
296 
297  //------------------------------------------------------------------------------------------------
298  override void ModeClear(EGadgetMode mode)
299  {
300  super.ModeClear(mode);
301 
302  if (mode == EGadgetMode.IN_HAND)
303  {
304  m_bActivated = false;
305  UpdateCompassState();
306  }
307  }
308 
309  //------------------------------------------------------------------------------------------------
310  override void ActivateGadgetUpdate()
311  {
312  super.ActivateGadgetUpdate();
313 
314  InventoryItemComponent itemComponent = InventoryItemComponent.Cast(GetOwner().FindComponent(InventoryItemComponent));
315  if (itemComponent)
316  itemComponent.ActivateOwner(true); // required for the procedural animations to function
317  }
318 
319  //------------------------------------------------------------------------------------------------
320  override void DeactivateGadgetUpdate()
321  {
322  super.DeactivateGadgetUpdate();
323 
324  InventoryItemComponent itemComponent = InventoryItemComponent.Cast(GetOwner().FindComponent(InventoryItemComponent));
325  if (itemComponent)
326  itemComponent.ActivateOwner(false);
327  }
328 
329  //------------------------------------------------------------------------------------------------
330  override EGadgetType GetType()
331  {
332  return EGadgetType.COMPASS;
333  }
334 
335  //------------------------------------------------------------------------------------------------
336  override bool CanBeRaised()
337  {
338  return true;
339  }
340 
341  //------------------------------------------------------------------------------------------------
342  override bool IsUsingADSControls()
343  {
344  return true;
345  }
346 
347  //------------------------------------------------------------------------------------------------
348  override bool RplSave(ScriptBitWriter writer)
349  {
350  if (!super.RplSave(writer))
351  return false;
352 
353  writer.WriteBool(m_bActivated);
354 
355  return true;
356  }
357 
358  //------------------------------------------------------------------------------------------------
359  override bool RplLoad(ScriptBitReader reader)
360  {
361  if (!super.RplLoad(reader))
362  return false;
363 
364  reader.ReadBool(m_bActivated);
365 
366  UpdateCompassState();
367 
368  return true;
369  }
370 
371  //------------------------------------------------------------------------------------------------
372  override void Update(float timeSlice)
373  {
374  UpdateNeedleDirection(timeSlice);
375  UpdateNeedleShake(timeSlice);
376  }
377 
378  //------------------------------------------------------------------------------------------------
379  override void OnPostInit(IEntity owner)
380  {
381  super.OnPostInit(owner);
382 
383  m_PrefabData = SCR_CompassComponentClass.Cast( GetComponentData(owner) );
384  m_SignalManager = SignalsManagerComponent.Cast( owner.FindComponent( SignalsManagerComponent ) );
385 
386  CalculateConstants();
387  UpdateCompassState();
388  }
389 }
SCR_CompassComponent
Compass component.
Definition: SCR_CompassComponent.c:73
SCR_GadgetComponentClass
Definition: SCR_GadgetComponent.c:2
desc
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
Definition: SCR_RespawnBriefingComponent.c:17
SCR_Math
Definition: SCR_Math.c:1
SCR_ECompassType
SCR_ECompassType
Compass type.
Definition: SCR_CompassComponent.c:3
m_SignalManager
protected SignalsManagerComponent m_SignalManager
Definition: SCR_WristwatchComponent.c:55
Attribute
typedef Attribute
Post-process effect of scripted camera.
ADRIANOV
ADRIANOV
Definition: SCR_CompassComponent.c:4
GetOwner
IEntity GetOwner()
Owner entity of the fuel tank.
Definition: SCR_FuelNode.c:128
InventoryItemComponent
Definition: InventoryItemComponent.c:12
SY183
SY183
Definition: SCR_CompassComponent.c:2
EntityEditorProps
enum SCR_ECompassType EntityEditorProps(category:"GameScripted/Gadgets", description:"Compass", color:"0 0 255 255")
Prefab data class for compass component.
Definition: SCR_CompassComponent.c:10
params
Configs ServerBrowser KickDialogs params
Definition: SCR_NotificationSenderComponent.c:24
m_PrefabData
protected SCR_WristwatchComponentClass m_PrefabData
Definition: SCR_WristwatchComponent.c:54
category
params category
Definition: SCR_VehicleDamageManagerComponent.c:180