Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_RadioComponent.c
Go to the documentation of this file.
3 {
6 }
7 
9 enum ERadioType
10 {
11  ANPRC68,
12  ANPRC77,
13  R148,
14  R107M
15 }
16 
18 enum EFreqUnit
19 {
20  KHZ = 0,
21  MHZ = 1
22 }
23 
25 class SCR_RadioProcAnimCtx
26 {
27  int sAnimSignal;
28  float fStartVal;
29  float fEndVal;
30  float fAnimSpeed;
31  float fTimeSlice;
32  bool bInProgress;
33 }
34 
35 [EntityEditorProps(category: "GameScripted/Gadgets", description: "Radio gadget", color: "0 0 255 255")]
36 class SCR_RadioComponentClass : SCR_GadgetComponentClass
37 {
38 }
39 
40 class SCR_RadioComponent : SCR_GadgetComponent
41 {
42  [Attribute("0", UIWidgets.ComboBox, "Radio category", "", ParamEnumArray.FromEnum(ERadioCategory), category: "Radio")]
43  private int m_iRadioCategory;
44 
45  [Attribute("0", UIWidgets.ComboBox, "Radio type", "", ParamEnumArray.FromEnum(ERadioType), category: "Radio")]
46  private int m_iRadioType;
47 
48  private bool m_bIsPowered = true; // radio on/off toggle
49  private BaseRadioComponent m_BaseRadioComp;
50  private SignalsManagerComponent m_SignalManager;
51 
52  // signals
53  protected bool m_bSignalInit = false;
54  protected int m_iSignalPower = -1;
55  protected int m_iSignalChannelKhz = -1;
56  protected int m_iSignalChannelMhz = -1;
57 
58  // proc anims
59  private ref array<ref SCR_RadioProcAnimCtx> m_aProcAnims = new array<ref SCR_RadioProcAnimCtx>();
60  private bool m_bAnimInProgress;
61 
62  //------------------------------------------------------------------------------------------------
64  void RadioToggle()
65  {
66  m_BaseRadioComp.SetPower( !m_BaseRadioComp.IsPowered() );
67  m_bIsPowered = m_BaseRadioComp.IsPowered();
68 
69  if (m_bIsPowered)
70  {
71  if ( m_iRadioType == ERadioType.ANPRC68 || ERadioType.ANPRC77 )
72  SetKnobAnim(m_iSignalPower, 1, 0.3, false);
73  }
74  else
75  {
76  if ( m_iRadioType == ERadioType.ANPRC68 || ERadioType.ANPRC77 )
77  SetKnobAnim(m_iSignalPower, 0, 0.3, false);
78  }
79  }
80 
81  //------------------------------------------------------------------------------------------------
85  bool ChangeFrequencyStep(bool direction)
86  {
87  if (!m_BaseRadioComp.IsPowered() || m_bAnimInProgress)
88  return false;
89 
90  string strUp = "UP";
91  string strDown = "DOWN";
92 
93  BaseTransceiver tsv = m_BaseRadioComp.GetTransceiver(0);
94  if (!tsv)
95  return false;
96 
97  int freq = tsv.GetFrequency();
98  int freqMax = tsv.GetMaxFrequency();
99  int freqMin = tsv.GetMinFrequency();
100 
101  if ( ( freq + tsv.GetFrequencyResolution() ) > freqMax && direction)
102  return false;
103  else if ( ( freq - tsv.GetFrequencyResolution() ) < freqMin && !direction)
104  return false;
105  else
106  {
107  if (direction)
108  freq += tsv.GetFrequencyResolution();
109  else
110  freq -= tsv.GetFrequencyResolution();
111 
112  //FIXME: Do not even try to change frequency without PlayerController
113  PlayerController pc = GetGame().GetPlayerController();
114  if (pc)
115  {
116  RadioHandlerComponent rhc = RadioHandlerComponent.Cast(pc.FindComponent(RadioHandlerComponent));
117  if (rhc)
118  {
119  rhc.SetFrequency(tsv, freq);
120  }
121  }
122 
123  float targetAngle;
124 
125  // proc anims
126  if ( m_iRadioType != ERadioType.ANPRC68 )
127  {
128  targetAngle = GetKnobAngle(EFreqUnit.MHZ);
129  SetKnobAnim(m_iSignalChannelMhz, targetAngle, 0.3, true);
130  }
131 
132  targetAngle = GetKnobAngle(EFreqUnit.KHZ);
133  SetKnobAnim(m_iSignalChannelKhz, targetAngle, 0.3, false);
134  }
135 
136  return true;
137  }
138 
139  //------------------------------------------------------------------------------------------------
143  private float GetKnobAngle(EFreqUnit freqUnit)
144  {
145  int step, stepsCount;
146  int currentStep = 0;
147 
148  stepsCount = GetKnobAnimStepCount(freqUnit);
149  BaseTransceiver tsv = m_BaseRadioComp.GetTransceiver(0);
150  if (!tsv)
151  return 0.0;
152 
153  step = (tsv.GetMinFrequency() - tsv.GetFrequency()) * -1;
154 
155  // Special case of preset number of channels
156  if (m_iRadioType == ERadioType.ANPRC68)
157  {
158  if (step > 0)
159  currentStep = step/tsv.GetFrequencyResolution();
160  }
161  // MHz, looking for the first two digits of a 5 digits frequency, steps are based on models dial
162  else if (freqUnit == EFreqUnit.MHZ)
163  {
164  if (step > 0)
165  currentStep = Math.Floor(step/1000);
166  }
167  // kHz
168  else
169  {
170  if (step >= 1000)
171  {
172  while (step >= 1000)
173  {
174  step -= 1000;
175  }
176  }
177 
178  // half steps 050, 150 etc
179  if ((step/50) % 2 == 0)
180  currentStep = 0;
181  else
182  currentStep = 1;
183 
184  step = Math.Floor(step/100);
185  currentStep = currentStep + (step * 2); // 20 steps(000 - 100) instead of 10 + possible half step (050)
186  }
187 
188  return currentStep * (360/stepsCount);
189 
190  }
191 
192  //------------------------------------------------------------------------------------------------
193  // Proc anims
194  //------------------------------------------------------------------------------------------------
195 
196  //------------------------------------------------------------------------------------------------
198  private void UpdateKnobState()
199  {
200  bool state;
201 
202  if (m_bIsPowered)
203  state = 1;
204  else
205  state = 0;
206 
207  if (!m_SignalManager)
208  return;
209 
210  if (!m_bSignalInit)
211  InitSignals();
212 
213  m_SignalManager.SetSignalValue( m_iSignalPower, (float)state );
214  m_SignalManager.SetSignalValue( m_iSignalChannelKhz, GetKnobAngle(EFreqUnit.KHZ) );
215 
216  if ( m_iRadioType != ERadioType.ANPRC68 )
217  m_SignalManager.SetSignalValue( m_iSignalChannelMhz, GetKnobAngle(EFreqUnit.MHZ) );
218  }
219 
220  //------------------------------------------------------------------------------------------------
226  private void SetKnobAnim(int signal, float targetAngle, float speed, bool clumpAnim)
227  {
228  if (m_bAnimInProgress || !m_SignalManager)
229  return;
230 
231  SCR_RadioProcAnimCtx animCtx = new SCR_RadioProcAnimCtx();
232  animCtx.sAnimSignal = signal;
233  animCtx.fStartVal = m_SignalManager.GetSignalValue(signal);
234  animCtx.fEndVal = targetAngle;
235  animCtx.fAnimSpeed = speed;
236  animCtx.fTimeSlice = 0;
237  animCtx.bInProgress = true;
238 
239  m_aProcAnims.Insert(animCtx);
240 
241  if (!clumpAnim)
242  {
243  m_bAnimInProgress = true;
245  }
246  }
247 
248  //------------------------------------------------------------------------------------------------
251  private void AnimKnob(float timeSlice)
252  {
253  int inProgress;
254 
255  for ( int i = 0; i < m_aProcAnims.Count(); i++ )
256  {
257  SCR_RadioProcAnimCtx animCtx = m_aProcAnims[i];
258  if (!animCtx)
259  continue;
260 
261  if (animCtx.bInProgress)
262  inProgress++;
263 
264  float newAngle;
265  animCtx.fTimeSlice += timeSlice / animCtx.fAnimSpeed;
266 
267  // if ended
268  if ( animCtx.fTimeSlice >= 1 )
269  {
270  animCtx.bInProgress = false;
271  newAngle = animCtx.fEndVal;
272  }
273  else
274  {
275  // Turn counter clockwise if closer
276  if ( Math.AbsFloat(animCtx.fStartVal - animCtx.fEndVal) > 180 )
277  {
278  if ( animCtx.fStartVal < 0)
279  animCtx.fStartVal += 360;
280  else
281  animCtx.fStartVal -= 360;
282  }
283 
284  float lerp = Math.Lerp(animCtx.fStartVal, animCtx.fEndVal, animCtx.fTimeSlice);
285  newAngle = lerp;
286  }
287 
288  m_SignalManager.SetSignalValue(animCtx.sAnimSignal, newAngle);
289  }
290 
291  if (inProgress <= 0)
292  {
293  m_bAnimInProgress = false;
294  m_aProcAnims.Clear();
296  }
297  }
298 
299  //------------------------------------------------------------------------------------------------
303  private int GetKnobAnimStepCount(EFreqUnit freqUnit)
304  {
305  if ( m_iRadioType == ERadioType.ANPRC68 )
306  {
307  return 10;
308  }
309  else if ( m_iRadioType == ERadioType.R148 )
310  {
311  if (freqUnit == EFreqUnit.MHZ)
312  return 15;
313  else
314  return 20;
315  }
316  else if ( m_iRadioType == ERadioType.ANPRC77 )
317  {
318  if (freqUnit == EFreqUnit.MHZ)
319  return 24; // 22 + 1 empty & +1 duplicated
320  else
321  return 24; // 20 +4 empty ones
322  }
323 
324  return 1;
325  }
326 
327  //------------------------------------------------------------------------------------------------
329  protected void InitSignals()
330  {
331  // cache signals
332  m_iSignalPower = m_SignalManager.FindSignal("Power");
333  m_iSignalChannelKhz = m_SignalManager.FindSignal("Channel_k");
334  m_iSignalChannelMhz = m_SignalManager.FindSignal("CHannel_M");
335 
336  if (m_iSignalPower != -1 && m_iSignalChannelKhz != -1 && m_iSignalChannelMhz != -1)
337  m_bSignalInit = true;
338  }
339 
340  //------------------------------------------------------------------------------------------------
341  // Overrides
342  //------------------------------------------------------------------------------------------------
343 
344  //------------------------------------------------------------------------------------------------
345  override void ModeSwitch(EGadgetMode mode, IEntity charOwner)
346  {
347  super.ModeSwitch(mode, charOwner);
348 
349  // Update knobs
350  UpdateKnobState();
351  }
352 
353  //------------------------------------------------------------------------------------------------
354  override void ActivateGadgetUpdate()
355  {
356  super.ActivateGadgetUpdate();
357 
358  InventoryItemComponent itemComponent = InventoryItemComponent.Cast(GetOwner().FindComponent(InventoryItemComponent));
359  if (itemComponent)
360  itemComponent.ActivateOwner(true); // required for the procedural animations to function
361  }
362 
363  //------------------------------------------------------------------------------------------------
364  override void DeactivateGadgetUpdate()
365  {
366  super.DeactivateGadgetUpdate();
367 
368  InventoryItemComponent itemComponent = InventoryItemComponent.Cast(GetOwner().FindComponent(InventoryItemComponent));
369  if (itemComponent)
370  itemComponent.ActivateOwner(false);
371  }
372 
373  //------------------------------------------------------------------------------------------------
374  override void UpdateVisibility(EGadgetMode mode)
375  {
376  if (m_iRadioCategory != ERadioCategory.MANPACK) // let radio backpack visibility be handled by inventory
377  super.UpdateVisibility(mode);
378  }
379 
380  //------------------------------------------------------------------------------------------------
381  override EGadgetType GetType()
382  {
383  if (m_iRadioCategory == ERadioCategory.MANPACK)
384  return EGadgetType.RADIO_BACKPACK;
385  else
386  return EGadgetType.RADIO;
387  }
388 
389  //------------------------------------------------------------------------------------------------
390  override bool CanBeHeld()
391  {
392  return true;
393  }
394 
395  //------------------------------------------------------------------------------------------------
396  override bool IsVisibleEquipped()
397  {
398  if (m_iRadioCategory == ERadioCategory.MANPACK)
399  return true;
400  else
401  return false;
402  }
403 
404  //------------------------------------------------------------------------------------------------
406  BaseRadioComponent GetRadioComponent()
407  {
408  return m_BaseRadioComp;
409  }
410 
411  //------------------------------------------------------------------------------------------------
412  override void Update(float timeSlice)
413  {
414  // knob anim
415  if (!m_bAnimInProgress)
416  {
418  return;
419  }
420 
421  AnimKnob(timeSlice);
422  }
423 
424  //------------------------------------------------------------------------------------------------
425  override void OnPostInit(IEntity owner)
426  {
427  super.OnPostInit(owner);
428 
429  // BaseRadioComponent
430  m_BaseRadioComp = BaseRadioComponent.Cast(owner.FindComponent(BaseRadioComponent));
431  if (!m_BaseRadioComp)
432  Print("SCR_RadioEntity: Failed acquiring BaseRadioComponent", LogLevel.WARNING);
433 
434  // signal manager
435  m_SignalManager = SignalsManagerComponent.Cast(owner.FindComponent( SignalsManagerComponent ) );
436  }
437 }
direction
vector direction
Definition: SCR_DestructibleTreeV2.c:31
GetType
override EGadgetType GetType()
Definition: SCR_CampaignBuildingGadgetToolComponent.c:52
ERadioCategory
ERadioCategory
Radio slot.
Definition: SCR_RadioComponent.c:2
EntityEditorProps
enum EQueryType EntityEditorProps(category:"GameScripted/Sound", description:"THIS IS THE SCRIPT DESCRIPTION.", color:"0 0 255 255")
Definition: SCR_AmbientSoundsComponent.c:12
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
SCR_GadgetComponentClass
Definition: SCR_GadgetComponent.c:2
ModeSwitch
override void ModeSwitch(EGadgetMode mode, IEntity charOwner)
Definition: SCR_CampaignBuildingGadgetToolComponent.c:68
PERSONAL
@ PERSONAL
Definition: SCR_RadioComponent.c:4
DeactivateGadgetUpdate
override void DeactivateGadgetUpdate()
Definition: SCR_WristwatchComponent.c:161
MANPACK
@ MANPACK
Definition: SCR_RadioComponent.c:5
m_SignalManager
protected SignalsManagerComponent m_SignalManager
Definition: SCR_WristwatchComponent.c:55
IsVisibleEquipped
override bool IsVisibleEquipped()
Definition: SCR_BinocularsComponent.c:106
Attribute
typedef Attribute
Post-process effect of scripted camera.
ActivateGadgetUpdate
override void ActivateGadgetUpdate()
Definition: SCR_WristwatchComponent.c:151
GetRadioComponent
BaseRadioComponent GetRadioComponent(PlayerController playerController, ChimeraCharacter character)
Definition: SCR_CampaignTaskNetworkComponent.c:234
Update
override void Update(float timeSlice)
Definition: SCR_CampaignBuildingGadgetToolComponent.c:28
OnPostInit
override void OnPostInit(IEntity owner)
Called on PostInit when all components are added.
Definition: SCR_AIConfigComponent.c:72
R148
enum ERadioCategory R148
BaseTransceiver
Definition: BaseTransceiver.c:12
GetOwner
IEntity GetOwner()
Owner entity of the fuel tank.
Definition: SCR_FuelNode.c:128
UpdateVisibility
private void UpdateVisibility()
Definition: SCR_InfoDisplayExtended.c:384
InventoryItemComponent
Definition: InventoryItemComponent.c:12
ANPRC77
enum ERadioCategory ANPRC77
ANPRC68
enum ERadioCategory ANPRC68
Radio model.
category
params category
Definition: SCR_VehicleDamageManagerComponent.c:180
KHZ
enum ERadioCategory KHZ
Frequency unit prefix.