Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_CharacterControllerComponent.c
Go to the documentation of this file.
1 [ComponentEditorProps(category: "GameScripted/Character", description: "Scripted character controller", icon: HYBRID_COMPONENT_ICON)]
3 {
4 }
5 
6 //------------------------------------------------------------------------------------------------
7 void OnPlayerDeathWithParam(SCR_CharacterControllerComponent characterController, IEntity killerEntity, notnull Instigator killer);
9 typedef ScriptInvokerBase<OnPlayerDeathWithParam> OnPlayerDeathWithParamInvoker;
10 
11 //------------------------------------------------------------------------------------------------
12 void OnControlledByPlayer(IEntity ownerEntity, bool controlled);
14 typedef ScriptInvokerBase<OnControlledByPlayer> OnControlledByPlayerInvoker;
15 
16 //------------------------------------------------------------------------------------------------
18 typedef ScriptInvokerBase<OnLifeStateChanged> OnLifeStateChangedInvoker;
19 
20 //------------------------------------------------------------------------------------------------
21 void OnItemUseBegan(IEntity item, ItemUseParameters animParams);
23 typedef ScriptInvokerBase<OnItemUseBegan> OnItemUseBeganInvoker;
24 
25 //------------------------------------------------------------------------------------------------
26 void OnItemUseEnded(IEntity item, bool successful, ItemUseParameters animParams);
28 typedef ScriptInvokerBase<OnItemUseEnded> OnItemUseEndedInvoker;
29 
30 //------------------------------------------------------------------------------------------------
31 void OnItemUseFinished(IEntity item, bool successful, ItemUseParameters animParams);
33 typedef ScriptInvokerBase<OnItemUseFinished> OnItemUseFinishedInvoker;
34 
35 class SCR_CharacterControllerComponent : CharacterControllerComponent
36 {
37  [Attribute(defvalue: "10", uiwidget: UIWidgets.EditBox, params:"1 inf 0.1", desc: "Maximum duration it takes for character to drown\n[s]")]
38  protected float m_fDrowningDuration;
39 
40  // Private members
41  protected SCR_CharacterCameraHandlerComponent m_CameraHandler; // Set from the camera handler itself
42  protected SCR_MeleeComponent m_MeleeComponent;
43  protected bool m_bOverrideActions = true;
44  protected bool m_bInspectionFocus;
45  protected bool m_bCharacterIsDrowning;
46  protected float m_fDrowningTime;
47  protected ref SCR_ScriptedCharacterInputContext m_pScrInputContext;
48 
49  // Character event invokers
50  ref ScriptInvokerVoid m_OnPlayerDeath = new ScriptInvokerVoid();
51  ref OnPlayerDeathWithParamInvoker m_OnPlayerDeathWithParam = new OnPlayerDeathWithParamInvoker(); // has a getter!
52  ref OnLifeStateChangedInvoker m_OnLifeStateChanged = new OnLifeStateChangedInvoker();
53  ref OnControlledByPlayerInvoker m_OnControlledByPlayer = new OnControlledByPlayerInvoker();
54  ref ScriptInvokerFloat2<float> m_OnPlayerDrowning = new ScriptInvokerFloat2();
55  ref ScriptInvokerVoid m_OnPlayerStopDrowning = new ScriptInvokerVoid();
56 
57  // Gadget event invokers
58  ref ScriptInvoker<IEntity, bool, bool> m_OnGadgetStateChangedInvoker = new ScriptInvoker<IEntity, bool, bool>();
59  ref ScriptInvoker<IEntity, bool> m_OnGadgetFocusStateChangedInvoker = new ScriptInvoker<IEntity, bool>();
60 
61  // Item event invokers
62  ref OnItemUseBeganInvoker m_OnItemUseBeganInvoker = new OnItemUseBeganInvoker();
63  ref OnItemUseEndedInvoker m_OnItemUseEndedInvoker = new OnItemUseEndedInvoker();
64  // called when all listeners reacted on ItemUseEnded invoker - may delete the item now thus listerners to ItemUseFinished may get first parameter null!
65  ref OnItemUseFinishedInvoker m_OnItemUseFinishedInvoker = new OnItemUseFinishedInvoker();
66  protected ref ScriptInvoker<AnimationEventID, AnimationEventID, int, float, float> m_OnAnimationEvent;
67 
68  // Diagnostics, debugging
69  #ifdef ENABLE_DIAG
70  private static bool s_bDiagRegistered;
71  private static bool m_bEnableDebugUI;
72  private CharacterAnimationComponent m_AnimComponent;
73  private Widget m_wDebugRootWidget;
74  private ECharacterStance m_bDebugLastStance = ECharacterStance.STAND;
75  #endif
76 
77  //------------------------------------------------------------------------------------------------
81  bool CanInteract()
82  {
83  if (GetLifeState() != ECharacterLifeState.ALIVE)
84  return false;
85 
86  if (IsUsingItem())
87  return false;
88 
89  if (IsClimbing())
90  return false;
91 
92  ChimeraCharacter character = GetCharacter();
93  if (!character || character.IsInVehicleADS())
94  return false;
95 
96  // Disable in vehicle 3pp
97  if (character.IsInVehicle() && IsInThirdPersonView())
98  return false;
99 
100  if (GetIsWeaponDeployed())
101  return false;
102 
103  return true;
104  }
105 
106  //------------------------------------------------------------------------------------------------
107  override void OnConsciousnessChanged(bool conscious)
108  {
109  if (GetLifeState() != ECharacterLifeState.INCAPACITATED)
110  return;
111 
112  AIControlComponent aiControl = AIControlComponent.Cast(GetOwner().FindComponent(AIControlComponent));
113  if (!aiControl || !aiControl.IsAIActivated())
114  return;
115 
116  IEntity currentWeapon;
117  BaseWeaponManagerComponent wpnMan = GetWeaponManagerComponent();
118  if (wpnMan && wpnMan.GetCurrentWeapon())
119  currentWeapon = wpnMan.GetCurrentWeapon().GetOwner();
120 
121  if (currentWeapon)
122  {
123  bool dropGrenade = false;
124 
125  SCR_CharacterCommandHandlerComponent handler = SCR_CharacterCommandHandlerComponent.Cast(GetAnimationComponent().GetCommandHandler());
126 
127  EWeaponType wt = wpnMan.GetCurrentWeapon().GetWeaponType();
128  if (currentWeapon.FindComponent(GrenadeMoveComponent))
129  {
130  BaseTriggerComponent triggerComp = BaseTriggerComponent.Cast(currentWeapon.FindComponent(BaseTriggerComponent));
131 
132  if ((triggerComp && triggerComp.WasTriggered()) || (handler && handler.IsThrowingAction()))
133  {
134  dropGrenade = true;
135  }
136  }
137 
138  if (dropGrenade)
139  handler.DropLiveGrenadeFromHand(false);
140  else
141  TryEquipRightHandItem(null, EEquipItemType.EEquipTypeUnarmedContextual, true);
142  }
143  }
144 
145  //------------------------------------------------------------------------------------------------
147  ScriptInvoker GetOnAnimationEvent()
148  {
149  if (!m_OnAnimationEvent)
150  m_OnAnimationEvent = new ScriptInvoker();
151 
152  return m_OnAnimationEvent;
153  }
154 
155  //------------------------------------------------------------------------------------------------
156  override void OnGadgetStateChanged(IEntity gadget, bool isInHand, bool isOnGround)
157  {
158  m_OnGadgetStateChangedInvoker.Invoke(gadget, isInHand, isOnGround);
159  }
160 
161  //------------------------------------------------------------------------------------------------
162  override void OnGadgetFocusStateChanged(IEntity gadget, bool isFocused)
163  {
164  m_OnGadgetFocusStateChangedInvoker.Invoke(gadget, isFocused);
165  }
166 
167  //------------------------------------------------------------------------------------------------
168  override void OnItemUseBegan(ItemUseParameters itemUseParams)
169  {
170  m_OnItemUseBeganInvoker.Invoke(itemUseParams.GetEntity(), itemUseParams);
171  }
172 
173  //------------------------------------------------------------------------------------------------
174  override void OnItemUseEnded(ItemUseParameters itemUseParams, bool successful)
175  {
176  m_OnItemUseEndedInvoker.Invoke(itemUseParams.GetEntity(), successful, itemUseParams);
177  // now all interested in non-null item have listened, we can call Finished to delete the item
178  m_OnItemUseFinishedInvoker.Invoke(itemUseParams.GetEntity(), successful, itemUseParams);
179  }
180 
181  //------------------------------------------------------------------------------------------------
182  protected override void OnAnimationEvent(AnimationEventID animEventType, AnimationEventID animUserString, int intParam, float timeFromStart, float timeToEnd)
183  {
184  if (m_OnAnimationEvent)
185  m_OnAnimationEvent.Invoke(animEventType, animUserString, intParam, timeFromStart, timeToEnd);
186  }
187 
188  //------------------------------------------------------------------------------------------------
189  // handling of melee events. Sends true if melee started, false, when melee ends
190  override void OnMeleeDamage(bool started)
191  {
192  m_MeleeComponent.SetMeleeAttackStarted(started);
193  }
194 
195  //------------------------------------------------------------------------------------------------
197  ScriptInvokerVoid GetOnPlayerDeath()
198  {
199  return m_OnPlayerDeath;
200  }
201 
202  //------------------------------------------------------------------------------------------------
204  OnPlayerDeathWithParamInvoker GetOnPlayerDeathWithParam()
205  {
206  return m_OnPlayerDeathWithParam;
207  }
208 
209  //------------------------------------------------------------------------------------------------
210  override void OnDeath(IEntity instigatorEntity, notnull Instigator instigator)
211  {
212  m_OnPlayerDeath.Invoke();
213  m_OnPlayerDeathWithParam.Invoke(this, instigatorEntity, instigator);
214 
216  if (pc && m_CameraHandler && m_CameraHandler.IsInThirdPerson())
217  pc.m_bRetain3PV = true;
218 
219  IEntity character = GetCharacter();
220  auto garbageSystem = SCR_GarbageSystem.GetByEntityWorld(character);
221  if (garbageSystem)
222  garbageSystem.Insert(character);
223  }
224 
225  //------------------------------------------------------------------------------------------------
226  override void OnLifeStateChanged(ECharacterLifeState previousLifeState, ECharacterLifeState newLifeState)
227  {
228  m_OnLifeStateChanged.Invoke(previousLifeState, newLifeState);
229 
230  ChimeraCharacter char = GetCharacter();
231  if (!char)
232  return;
233 
234  IEntity vehicle = CompartmentAccessComponent.GetVehicleIn(char);
235  if (!vehicle)
236  return;
237 
239  if (!vehicleFactionAff)
240  return;
241 
242  vehicleFactionAff.UpdateOccupantsCount();
243  }
244 
245  //------------------------------------------------------------------------------------------------
246  override bool GetCanMeleeAttack()
247  {
248  if (!m_MeleeComponent)
249  return false;
250 
251  if (IsFalling())
252  return false;
253 
254  if (GetStance() == ECharacterStance.PRONE)
255  return false;
256 
257  // TODO: Gadget melee weapon properties in case we want to be able to have melee component, like a shovel?
258  if (IsGadgetInHands())
259  return false;
260 
262  BaseWeaponManagerComponent weaponManager = GetWeaponManagerComponent();
263  if (weaponManager && !SCR_WeaponLib.CurrentWeaponHasComponent(weaponManager, SCR_MeleeWeaponProperties))
264  return false;
265 
266  return true;
267  }
268 
269  override bool GetCanEquipGadget(IEntity gadget)
270  {
271  SCR_CharacterCommandHandlerComponent handler = SCR_CharacterCommandHandlerComponent.Cast(GetAnimationComponent().GetCommandHandler());
272  if (handler.IsLoitering() || GetScrInputContext().m_iLoiteringType != -1)
273  return false;
274 
275  return true;
276  }
277 
278  //------------------------------------------------------------------------------------------------
281  override bool OnPerformAction()
282  {
283  return m_bOverrideActions;
284  }
285 
286  //------------------------------------------------------------------------------------------------
287  override void OnInit(IEntity owner)
288  {
289  ChimeraCharacter character = GetCharacter();
290  if (!character)
291  return;
292 
293  if (!m_MeleeComponent)
294  m_MeleeComponent = SCR_MeleeComponent.Cast(character.FindComponent(SCR_MeleeComponent));
295  if (!m_CameraHandler)
296  m_CameraHandler = SCR_CharacterCameraHandlerComponent.Cast(character.FindComponent(SCR_CharacterCameraHandlerComponent));
297 
298  #ifdef ENABLE_DIAG
299  if (!m_AnimComponent)
300  m_AnimComponent = CharacterAnimationComponent.Cast(character.FindComponent(CharacterAnimationComponent));
301  #endif
302 
303  m_pScrInputContext = new SCR_ScriptedCharacterInputContext();
304  }
305 
306  //------------------------------------------------------------------------------------------------
307  protected override void OnApplyControls(IEntity owner, float timeSlice)
308  {
309  if (GetScrInputContext().m_iLoiteringType >= 0)
310  {
311  SCR_CharacterCommandHandlerComponent handler = SCR_CharacterCommandHandlerComponent.Cast(GetAnimationComponent().GetCommandHandler());
312  if (!handler.IsLoitering())
313  {
314  if (TryStartLoiteringInternal())
315  return;
316  }
317  }
318  }
319 
320  //------------------------------------------------------------------------------------------------
321  protected override void UpdateDrowning(float timeSlice, vector waterLevel)
322  {
323  ChimeraCharacter char = GetCharacter();
324  if (!char)
325  return;
326 
327  CompartmentAccessComponent accesComp = char.GetCompartmentAccessComponent();
328  bool isInWatertightCompartment = accesComp && accesComp.GetCompartment() && accesComp.GetCompartment().GetIsWaterTight();
329 
330  float drowningTimeStartFX = 4;
331  if (waterLevel[2] > 0 && !isInWatertightCompartment)
332  {
333  if (m_fDrowningTime < drowningTimeStartFX && (m_fDrowningTime + timeSlice) > drowningTimeStartFX)
334  {
335  m_OnPlayerDrowning.Invoke(m_fDrowningDuration, drowningTimeStartFX);
336  m_bCharacterIsDrowning = true;
337  }
338 
339  m_fDrowningTime += timeSlice;
340  }
341  else
342  {
343  if (m_fDrowningTime != 0)
344  {
345  m_OnPlayerStopDrowning.Invoke();
346  m_bCharacterIsDrowning = false;
347  }
348 
349  m_fDrowningTime = 0;
350  return;
351  }
352 
354  if (!damageMan || !damageMan.GetResilienceHitZone())
355  return;
356 
357  if (m_fDrowningTime > m_fDrowningDuration)
358  {
359  damageMan.GetResilienceHitZone().HandleDamage(1000, EDamageType.TRUE, GetOwner());
360  damageMan.Kill(Instigator.CreateInstigator(char));
361  }
362  }
363 
364  //------------------------------------------------------------------------------------------------
366  float GetDrowningTime()
367  {
368  return m_fDrowningTime;
369  }
370 
371  //------------------------------------------------------------------------------------------------
373  bool IsCharacterDrowning()
374  {
375  return m_bCharacterIsDrowning;
376  }
377 
378  //------------------------------------------------------------------------------------------------
379  override bool ShouldAligningAdjustAimingAngles()
380  {
381  return IsAligningBeforeLoiter();
382  }
383 
384  //------------------------------------------------------------------------------------------------
386  bool IsAligningBeforeLoiter()
387  {
388  return GetScrInputContext().m_iLoiteringType != -1 && GetScrInputContext().m_bLoiteringShouldAlignCharacter && GetAnimationComponent().GetHeadingComponent().IsAligning();
389  }
390 
391  //------------------------------------------------------------------------------------------------
392  // why the SCR_ prefix?
393  override bool SCR_GetDisableMovementControls()
394  {
395  SCR_CharacterCommandHandlerComponent handler = SCR_CharacterCommandHandlerComponent.Cast(GetAnimationComponent().GetCommandHandler());
396  if (!handler)
397  return false;
398 
399  if (GetScrInputContext().m_iLoiteringType > 0)
400  {
401  bool isAligningBeforeLoiter = IsAligningBeforeLoiter();
402  bool isHolsteringBeforeLoiter = GetScrInputContext().m_iLoiteringShouldHolsterWeapon && IsChangingItem();
403 
404  if (isAligningBeforeLoiter || isHolsteringBeforeLoiter)
405  return true;
406  }
407 
408  return handler.IsLoitering();
409  }
410 
411  //------------------------------------------------------------------------------------------------
412  override void SCR_OnDisabledJumpAction()
413  {
414  SCR_CharacterCommandHandlerComponent handler = SCR_CharacterCommandHandlerComponent.Cast(GetAnimationComponent().GetCommandHandler());
415  if (!handler)
416  return;
417 
418  if (handler.IsLoitering())
419  StopLoitering(false);
420 
421  if (IsAligningBeforeLoiter())
422  {
423  CharacterHeadingAnimComponent headingComponent = GetAnimationComponent().GetHeadingComponent();
424  if (headingComponent)
425  {
426  headingComponent.ResetAligning();
427  GetScrInputContext().m_iLoiteringType = -1;
428  }
429  }
430  }
431 
432  //------------------------------------------------------------------------------------------------
433  // #ifdef ENABLE_DIAG
434  //------------------------------------------------------------------------------------------------
435  #ifdef ENABLE_DIAG
436  //------------------------------------------------------------------------------------------------
437  override void OnDiag(IEntity owner, float timeslice)
438  {
439  ChimeraCharacter character = GetCharacter();
440  if (!character || IsDead())
441  return;
442 
443  if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_CHARACTER_NOBANKING))
444  SetBanking(0);
445 
446  bool diagTransform = DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_CHARACTER_TRANSFORMATION);
447  bool bIsLocalCharacter = SCR_PlayerController.GetLocalControlledEntity() == character;
448 
449  // Character Transformation Diag
450  if (bIsLocalCharacter && diagTransform)
451  {
452  DbgUI.Begin("Character Transformation");
453  const string CHAR_POS = "X:\t%1\nY:\t%2\nZ:\t%3";
454  const string CHAR_ROT = "PITCH:\t%1\nYAW:\t%2\nROLL:\t%3";
455  const string CHAR_SCALE = "%1";
456  const string CHAR_AIM = "X:\t%1\nY:\t%2\nZ:\t%3";
457  vector pos = character.GetOrigin();
458  vector rot = character.GetYawPitchRoll();
459  float scale = character.GetScale();
460  vector aimRot = GetInputContext().GetAimingAngles();
461  string strPosition = string.Format(CHAR_POS, pos[0].ToString(), pos[1].ToString(), pos[2].ToString());
462  string strRotation = string.Format(CHAR_ROT, rot[1].ToString(), rot[0].ToString(), rot[2].ToString());
463  string strScale = string.Format(CHAR_SCALE, scale.ToString());
464  string strAiming = string.Format(CHAR_AIM, aimRot[0].ToString(), aimRot[1].ToString(), aimRot[2].ToString());
465  DbgUI.Text("POSITION:\n" + strPosition);
466  DbgUI.Text("ROTATION:\n" + strRotation);
467  DbgUI.Text("SCALE:" + strScale);
468  DbgUI.Text("AIMING ANGLES:\n" + strAiming);
469 
470  if (DbgUI.Button("Print plaintext to console"))
471  Print("TransformInfo:\nPOSITION:\n" + strPosition + "\nROTATION:\n" + strRotation + "\nSCALE:" + strScale + "\nAIMING ANGLES:\n" + strAiming, LogLevel.NORMAL);
472 
473  DbgUI.End();
474  }
475 
476  // Character Controller diag (inputs...)
477  m_bEnableDebugUI = bIsLocalCharacter && DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_CHARACTER_MENU);
478  if (m_bEnableDebugUI && !m_wDebugRootWidget) // Currently controlled player
479  CreateDebugUI();
480  else if (!m_bEnableDebugUI && m_wDebugRootWidget)
481  DeleteDebugUI();
482 
483  if (m_bEnableDebugUI)
484  UpdateDebugUI();
485  }
486 
487  //------------------------------------------------------------------------------------------------
488  private void ReloadDebugUI()
489  {
490  if (m_wDebugRootWidget)
491  DeleteDebugUI();
492 
493  CreateDebugUI();
494  }
495 
496  //------------------------------------------------------------------------------------------------
497  private void DeleteDebugUI()
498  {
499  m_wDebugRootWidget.RemoveFromHierarchy();
500  m_wDebugRootWidget = null;
501  }
502 
503  //------------------------------------------------------------------------------------------------
504  private void UpdateInputCircles()
505  {
506  if (!m_wDebugRootWidget || !m_AnimComponent)
507  return;
508 
509  Widget wInput = m_wDebugRootWidget.FindAnyWidget("Input");
510  if (!wInput)
511  return;
512 
513  WorkspaceWidget workspaceWidget = GetGame().GetWorkspace();
514 
515  float topSpeed = m_AnimComponent.GetTopSpeed(-1, false);
516 
517  TextWidget wMaxSpeed = TextWidget.Cast(wInput.FindAnyWidget("MaxSpeed"));
518  if (wMaxSpeed)
519  {
520  float speed = Math.Ceil(topSpeed * 10) * 0.1;
521  wMaxSpeed.SetText(speed.ToString() + "m/s");
522  }
523 
524  float ringSize = FrameSlot.GetSizeX(wInput);
525  float degSizeDivider = topSpeed * ringSize;
526  if (degSizeDivider > 0)
527  for (int spd = 0; spd < 3; spd++)
528  {
529  int spdType;
530  if (spd == 0)
531  spdType = EMovementType.WALK;
532  else
533  if (spd == 1)
534  spdType = EMovementType.RUN;
535  else
536  if (spd == 2)
537  spdType = EMovementType.SPRINT;
538 
539  int color;
540  if (spd == 0)
541  color = ARGB(255, 150, 255, 150);
542  else
543  if (spd == 1)
544  color = ARGB(255, 200, 200, 150);
545  else
546  if (spd == 2)
547  color = ARGB(255, 255, 150, 150);
548 
549  for (int deg = 0; deg < 360; deg++)
550  {
551  vector velInput = GetMovementVelocity();
552  float inputForward = velInput[2];
553  float inputRight = velInput[0];
554 
555  float degSize = m_AnimComponent.GetMaxSpeed(inputForward, inputRight, spdType) / degSizeDivider;
556  if (spdType == EMovementType.SPRINT && !IsSprinting())
557  degSize = 0;
558 
559  float degOff = (ringSize - degSize) * 0.5;
560 
561  string iRingname = "iRing_" + spd.ToString() + "_" + deg.ToString();
562 
563  ImageWidget wImg = ImageWidget.Cast(wInput.FindAnyWidget(iRingname));
564  if (!wImg)
565  {
566  wImg = ImageWidget.Cast(workspaceWidget.CreateWidget(WidgetType.ImageWidgetTypeID, WidgetFlags.BLEND | WidgetFlags.VISIBLE | WidgetFlags.STRETCH | WidgetFlags.NOWRAP, Color.FromInt(color), spd + 2, wInput));
567  wImg.LoadImageTexture(0, "{90DF4F065D08EF4E}UI/Textures/HUD_obsolete/character/input_360ringslice.edds");
568  wImg.SetRotation(deg);
569  wImg.SetName(iRingname);
570  }
571 
572  FrameSlot.SetAnchorMax(wImg, 0, 0);
573  FrameSlot.SetAnchorMin(wImg, 0, 0);
574  FrameSlot.SetSize(wImg, degSize, degSize);
575  FrameSlot.SetPos(wImg, degOff, degOff);
576  }
577  }
578  }
579 
580  //------------------------------------------------------------------------------------------------
581  private void CreateDebugUI()
582  {
583  m_wDebugRootWidget = GetGame().GetWorkspace().CreateWidgets("{C70DA11469BBAF67}UI/layouts/Debug/HUD_Debug_Character.layout", null);
584  UpdateInputCircles();
585  }
586 
587  //------------------------------------------------------------------------------------------------
588  private void UpdateDebugBoolWidget(string textWidgetName, bool isTrue, float time = 0)
589  {
590  TextWidget wTxt = TextWidget.Cast(m_wDebugRootWidget.FindAnyWidget(textWidgetName));
591  if (!wTxt)
592  return;
593 
594  time = Math.Ceil(time * 10) * 0.1;
595  if (isTrue)
596  {
597  wTxt.SetColorInt(ARGB(255, 160, 210, 255));
598  if (time != 0)
599  wTxt.SetText("YES (" + time.ToString() + ")");
600  else
601  wTxt.SetText("YES");
602  }
603  else
604  {
605  wTxt.SetColorInt(ARGB(255, 255, 160, 160));
606  if (time != 0)
607  wTxt.SetText("NO (" + time.ToString() + ")");
608  else
609  wTxt.SetText("NO");
610  }
611  }
612 
613  //------------------------------------------------------------------------------------------------
614  private void UpdateDebugUI()
615  {
616  ChimeraCharacter character = GetCharacter();
617 
618  // Reload debug UI for stance change
619  if (m_bDebugLastStance != GetStance())
620  {
621  m_bDebugLastStance = GetStance();
622  UpdateInputCircles();
623  }
624 
625  float topSpeed = 0;
626  if (m_AnimComponent)
627  topSpeed = m_AnimComponent.GetTopSpeed(-1, false);
628 
629  Widget wCenter = m_wDebugRootWidget.FindAnyWidget("Center");
630  Widget wCenter2 = m_wDebugRootWidget.FindAnyWidget("Center2");
631  Widget wCenter3 = m_wDebugRootWidget.FindAnyWidget("Center3");
632 
633  vector movementInput = GetMovementInput();
634  if (movementInput != vector.Zero)
635  {
636  float inputLength = movementInput.Length();
637  if (inputLength > 1)
638  movementInput *= 1 / inputLength;
639  }
640 
641  if (wCenter && wCenter2 && wCenter3 && topSpeed > 0)
642  {
643  float inputForward = movementInput[0];
644  float inputRight = movementInput[2];
645  float maxSpeed = m_AnimComponent.GetMaxSpeed(inputForward, inputRight, GetCurrentMovementPhase());
646  float moveScale = maxSpeed / topSpeed;
647  float x = movementInput[0] * moveScale * 0.5 + 0.5;
648  float y = -movementInput[2] * moveScale * 0.5 + 0.5;
649  FrameSlot.SetAnchorMin(wCenter, x, y);
650  FrameSlot.SetAnchorMax(wCenter, x, y);
651 
652  vector moveLocal = m_AnimComponent.GetInertiaSpeed();
653  x = (moveLocal[0] / topSpeed) * 0.5 + 0.5;
654  y = (-moveLocal[2] / topSpeed) * 0.5 + 0.5;
655  FrameSlot.SetAnchorMin(wCenter2, x, y);
656  FrameSlot.SetAnchorMax(wCenter2, x, y);
657 
658  moveLocal = character.VectorToLocal(GetVelocity());
659  x = (moveLocal[0] / topSpeed) * 0.5 + 0.5;
660  y = (-moveLocal[2] / topSpeed) * 0.5 + 0.5;
661  FrameSlot.SetAnchorMin(wCenter3, x, y);
662  FrameSlot.SetAnchorMax(wCenter3, x, y);
663  }
664 
665  TextWidget wSpeed = TextWidget.Cast(m_wDebugRootWidget.FindAnyWidget("Speed"));
666  TextWidget wSpeed2 = TextWidget.Cast(m_wDebugRootWidget.FindAnyWidget("Speed2"));
667  if (wSpeed && wSpeed2)
668  {
669  float speed = Math.Ceil(m_AnimComponent.GetInertiaSpeed().Length() * 10) * 0.1;
670  wSpeed.SetText(speed.ToString() + "m/s");
671 
672  speed = Math.Ceil(GetVelocity().Length() * 10) * 0.1;
673  wSpeed2.SetText(speed.ToString() + "m/s");
674  }
675 
676  TextWidget wAdjustedSpeed = TextWidget.Cast(m_wDebugRootWidget.FindAnyWidget("AdjustedSpeed"));
677  if (wAdjustedSpeed)
678  wAdjustedSpeed.SetText(GetDynamicSpeed().ToString());
679 
680  TextWidget wAdjustedStance = TextWidget.Cast(m_wDebugRootWidget.FindAnyWidget("AdjustedStance"));
681  if (wAdjustedStance)
682  wAdjustedStance.SetText(GetDynamicStance().ToString());
683 
684  UpdateDebugBoolWidget("ToggleSprint", GetIsSprintingToggle());
685  UpdateDebugBoolWidget("IsInADS", IsWeaponADS());
686  UpdateDebugBoolWidget("IsWeaponHolstered", !IsWeaponRaised());
687  UpdateDebugBoolWidget("CanFireWeapon", GetCanFireWeapon());
688  UpdateDebugBoolWidget("CanThrow", GetCanThrow());
689  UpdateDebugBoolWidget("InFreeLook", IsFreeLookEnabled());
690 
691  TextWidget wMovementAngle = TextWidget.Cast(m_wDebugRootWidget.FindAnyWidget("MovementAngle"));
692  CharacterCommandHandlerComponent handler = m_AnimComponent.GetCommandHandler();
693  if (!wMovementAngle || !handler)
694  return;
695 
696  CharacterCommandMove moveCmd = handler.GetCommandMove();
697  if (moveCmd)
698  {
699  float currAngle = moveCmd.GetMovementSlopeAngle();
700  wMovementAngle.SetText(currAngle.ToString() + "deg");
701  }
702  }
703 
704  //------------------------------------------------------------------------------------------------
705  // #endif ENABLE_DIAG
706  //------------------------------------------------------------------------------------------------
707  #endif
708 
709  //------------------------------------------------------------------------------------------------
710  override void OnPrepareControls(IEntity owner, ActionManager am, float dt, bool player)
711  {
712  if (am.GetActionTriggered("JumpOut") && CanJumpOutVehicleScript())
713  {
714  ChimeraCharacter character = ChimeraCharacter.Cast(owner);
715  CompartmentAccessComponent compAccess = character.GetCompartmentAccessComponent();
716 
717  BaseCompartmentSlot compartment = compAccess.GetCompartment();
718  if (compartment)
719  {
720  CompartmentUserAction action = compartment.GetJumpOutAction();
721  if (action && action.CanBePerformed(GetOwner()))
722  {
723  action.PerformAction(compartment.GetOwner(), GetOwner());
724  return;
725  }
726 
727  // Add the following once the correct action exists
728  //if (!action && compAccess.CanGetOutVehicle())
729  //{
730  // compAccess.GetOutVehicle(-1);
731  //}
732  }
733  }
734 
735  if (am.GetActionTriggered("GetOut") && CanGetOutVehicleScript())
736  {
737  ChimeraCharacter character = ChimeraCharacter.Cast(owner);
738  CompartmentAccessComponent compAccess = character.GetCompartmentAccessComponent();
739 
740  BaseCompartmentSlot compartment = compAccess.GetCompartment();
741  if (compartment)
742  {
743  CompartmentUserAction action = compartment.GetGetOutAction();
744  if (action && action.CanBePerformed(GetOwner()))
745  {
746  action.PerformAction(compartment.GetOwner(), GetOwner());
747  return;
748  }
749 
750  if (!action && compAccess.CanGetOutVehicle())
751  {
752  compAccess.GetOutVehicle(-1, false);
753  }
754  }
755  }
756 
757  if (GetStance() == ECharacterStance.PRONE)
758  {
759  float value = am.GetActionValue("CharacterRoll");
760  int rollValue = 0;
761  if (value < -0.5)
762  rollValue = 1;
763  else if (value > 0.5)
764  rollValue = 2;
765 
766  // If one wants to use hold action - it needs too be allowed on CharacterControllerComponent at character prefab or by calling EnableHoldInputForRoll(true) during construction/initialization
768  SetRoll(rollValue);
769  else if (rollValue != 0)
770  SetRoll(rollValue);
771  }
772  }
773 
774  //------------------------------------------------------------------------------------------------
775  // constructor
779  void SCR_CharacterControllerComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
780  {
781  #ifdef ENABLE_DIAG
782  if (System.IsCLIParam("CharacterDebugUI")) // If the startup parameter is set, enable the debug UI
783  m_bEnableDebugUI = true;
784 
785  if (!s_bDiagRegistered)
786  {
787  DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_CHARACTER_MENU, "", "Enable Debug UI", "Character");
788  DiagMenu.SetValue(SCR_DebugMenuID.DEBUGUI_CHARACTER_MENU, m_bEnableDebugUI);
789  DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_CHARACTER_NOBANKING, "", "Disable Banking", "Character");
790  DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_CHARACTER_TRANSFORMATION, "", "Enable transform info", "Character");
791  DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_CHARACTER_RECOIL_CAMERASHAKE_DISABLE, "", "Disable recoil cam shake", "Character");
792  DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_CHARACTER_ADDITIONAL_CAMERASHAKE_DISABLE, "", "Disable additional cam shake", "Character");
793  DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_CHARACTER_CAMERASHAKE_TEST_WINDOW, "", "Show shake diag", "Character");
794  DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_WEAPONS_ALLOW_INSPECTION_LOOKAT, "", "Inspection LookAt", "Character");
795  s_bDiagRegistered = true;
796  }
797  #endif
798  }
799 
800  //------------------------------------------------------------------------------------------------
801  // destructor
803  {
804  #ifdef ENABLE_DIAG
805  if (m_wDebugRootWidget)
806  DeleteDebugUI();
807  #endif
808  }
809 
810  //------------------------------------------------------------------------------------------------
814  void SetNextSightsFOVInfo(int direction = 1, bool allowCycling = false)
815  {
816  if (direction == 0)
817  return;
818 
819  SightsFOVInfo fovInfo = GetSightsFOVInfo();
820  if (!fovInfo)
821  return;
822 
823  SCR_BaseVariableSightsFOVInfo variableFovInfo = SCR_BaseVariableSightsFOVInfo.Cast(fovInfo);
824  if (!variableFovInfo)
825  return;
826 
827  if (direction > 0)
828  variableFovInfo.SetNext(allowCycling);
829  else
830  variableFovInfo.SetPrevious(allowCycling);
831  }
832 
833  //------------------------------------------------------------------------------------------------
836  void SetNextSights(int direction = 1)
837  {
838  // Check if we are in a turret and switch the turret's optics instead
839  SCR_ChimeraCharacter character = SCR_ChimeraCharacter.Cast(GetOwner());
840  Turret turret = Turret.Cast(character.GetParent());
841  if (turret)
842  {
843  TurretComponent turretComponent = TurretComponent.Cast(turret.FindComponent(TurretComponent));
844  if (direction > 0)
845  turretComponent.SwitchNextSights();
846  else
847  turretComponent.SwitchPrevSights();
848 
849  return;
850  }
851 
852  BaseWeaponManagerComponent weaponManager = GetWeaponManagerComponent();
853  if (!weaponManager)
854  return;
855 
856  BaseWeaponComponent weaponComponent = weaponManager.GetCurrentWeapon();
857  if (!weaponComponent)
858  return;
859 
860  if (direction > 0)
861  weaponComponent.SwitchNextSights();
862  else
863  weaponComponent.SwitchPrevSights();
864  }
865 
866  //------------------------------------------------------------------------------------------------
868  SightsFOVInfo GetSightsFOVInfo()
869  {
870  BaseWeaponManagerComponent weaponManager = GetWeaponManagerComponent();
871  if (!weaponManager)
872  return null;
873 
874  BaseWeaponComponent weaponComponent = weaponManager.GetCurrentWeapon();
875  if (!weaponComponent)
876  return null;
877 
878  BaseSightsComponent sightsComponent = weaponComponent.GetSights();
879  if (!sightsComponent)
880  return null;
881 
882  return sightsComponent.GetFOVInfo();
883  }
884 
885  //------------------------------------------------------------------------------------------------
886  protected override void OnControlledByPlayer(IEntity owner, bool controlled)
887  {
888  // Do initialisation/deinitialisation of character that was given/lost control by plyer here
889  if (controlled && owner == SCR_PlayerController.GetLocalControlledEntity())
890  {
891  GetGame().GetInputManager().AddActionListener("CharacterUnequipItem", EActionTrigger.DOWN, ActionUnequipItem);
892  GetGame().GetInputManager().AddActionListener("CharacterDropItem", EActionTrigger.DOWN, ActionDropItem);
893  GetGame().GetInputManager().AddActionListener("CharacterWeaponLowReady", EActionTrigger.DOWN, ActionWeaponLowReady);
894  GetGame().GetInputManager().AddActionListener("CharacterWeaponRaised", EActionTrigger.DOWN, ActionWeaponRaised);
895  GetGame().GetInputManager().AddActionListener("CharacterWeaponBipod", EActionTrigger.DOWN, ActionWeaponBipod);
896 
897  // TODO: This should be handled by camera handler itself
898  if (m_CameraHandler)
899  GetGame().GetInputManager().AddActionListener("SwitchCameraType", EActionTrigger.DOWN, m_CameraHandler.OnCameraSwitchPressed);
900  }
901  else
902  {
903  GetGame().GetInputManager().RemoveActionListener("CharacterUnequipItem", EActionTrigger.DOWN, ActionUnequipItem);
904  GetGame().GetInputManager().RemoveActionListener("CharacterDropItem", EActionTrigger.DOWN, ActionDropItem);
905  GetGame().GetInputManager().RemoveActionListener("CharacterWeaponLowReady", EActionTrigger.DOWN, ActionWeaponLowReady);
906  GetGame().GetInputManager().RemoveActionListener("CharacterWeaponRaised", EActionTrigger.DOWN, ActionWeaponRaised);
907  GetGame().GetInputManager().RemoveActionListener("CharacterWeaponBipod", EActionTrigger.DOWN, ActionWeaponBipod);
908 
909  // TODO: This should be handled by camera handler itself
910  if (m_CameraHandler)
911  GetGame().GetInputManager().RemoveActionListener("SwitchCameraType", EActionTrigger.DOWN, m_CameraHandler.OnCameraSwitchPressed);
912  }
913 
914  m_OnControlledByPlayer.Invoke(owner, controlled);
915 
916  // diiferentiate the inventory setup for player and AI
917  SCR_CharacterInventoryStorageComponent pCharInvComponent = SCR_CharacterInventoryStorageComponent.Cast(owner.FindComponent(SCR_CharacterInventoryStorageComponent));
918  if (pCharInvComponent)
919  pCharInvComponent.InitAsPlayer(owner, controlled);
920  }
921 
922  //------------------------------------------------------------------------------------------------
926  void ActionUnequipItem(float value = 0.0, EActionTrigger trigger = 0)
927  {
928  SCR_InventoryStorageManagerComponent storageManager = SCR_InventoryStorageManagerComponent.Cast(GetInventoryStorageManager());
929  if (!storageManager)
930  return;
931 
932  SCR_CharacterInventoryStorageComponent storage = storageManager.GetCharacterStorage();
933  if (storage)
934  storage.UnequipCurrentItem();
935  }
936 
937  //------------------------------------------------------------------------------------------------
941  void ActionDropItem(float value = 0.0, EActionTrigger trigger = 0)
942  {
943  SCR_InventoryStorageManagerComponent storageManager = SCR_InventoryStorageManagerComponent.Cast(GetInventoryStorageManager());
944  if (!storageManager)
945  return;
946 
947  SCR_CharacterInventoryStorageComponent storage = storageManager.GetCharacterStorage();
948  if (storage)
949  storage.DropCurrentItem();
950  }
951 
952  //------------------------------------------------------------------------------------------------
956  void ActionWeaponLowReady(float value = 0.0, EActionTrigger trigger = 0)
957  {
958  if (GetIsWeaponDeployed())
959  return;
960 
962  return;
963 
965  SetPartialLower(true);
966  }
967 
968  //------------------------------------------------------------------------------------------------
972  void ActionWeaponRaised(float value = 0.0, EActionTrigger trigger = 0)
973  {
974  if (!IsWeaponRaised())
975  SetWeaponRaised(true);
976 
977  if (IsPartiallyLowered())
978  SetPartialLower(false);
979  }
980 
981  //------------------------------------------------------------------------------------------------
985  void ActionWeaponBipod(float value = 0.0, EActionTrigger trigger = 0)
986  {
987  BaseWeaponManagerComponent weaponManager = GetWeaponManagerComponent();
988  if (!weaponManager)
989  return;
990 
991  BaseWeaponComponent weapon = weaponManager.GetCurrentWeapon();
992  if (!weapon || !weapon.HasBipod())
993  return;
994 
996  StopDeployment();
997 
998  weapon.SetBipod(!weapon.GetBipod());
999  }
1000 
1001  //------------------------------------------------------------------------------------------------
1002  protected override void OnInspectionModeChanged(bool newState)
1003  {
1004  m_bInspectionFocus = newState;
1005  }
1006 
1007  protected int m_iTargetContext;
1008 
1009  //------------------------------------------------------------------------------------------------
1010  protected override float GetInspectTargetLookAt(out vector targetAngles)
1011  {
1012  #ifdef ENABLE_DIAG
1013  if (!DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_WEAPONS_ALLOW_INSPECTION_LOOKAT))
1014  return 0;
1015  #else
1016  return 0; // Disabled for now
1017  #endif
1018 
1019  // Just for testing
1020  if (Debug.KeyState(KeyCode.KC_ADD))
1021  {
1022  ++m_iTargetContext;
1023  Debug.ClearKey(KeyCode.KC_ADD);
1024  m_bInspectionFocus = true;
1025  }
1026 
1027  if (Debug.KeyState(KeyCode.KC_SUBTRACT))
1028  {
1029  --m_iTargetContext;
1030  Debug.ClearKey(KeyCode.KC_SUBTRACT);
1031  m_bInspectionFocus = true;
1032  }
1033 
1034  if (!m_bInspectionFocus)
1035  return 0;
1036 
1037  vector aimChange = GetInputContext().GetAimChange();
1038  const float threshold = 0.001;
1039  if (Math.AbsFloat(aimChange[0]) > threshold || Math.AbsFloat(aimChange[1]) > threshold)
1040  {
1041  m_bInspectionFocus = false;
1042  return 0;
1043  } // not now
1044 
1045  IEntity ent = GetInspectEntity();
1046  if (!ent)
1047  return 0;
1048 
1049  SCR_InteractionHandlerComponent handler = SCR_InteractionHandlerComponent.Cast(GetGame().GetPlayerController().FindComponent(SCR_InteractionHandlerComponent));
1050  if (!handler)
1051  return 0;
1052 
1053  // Update target
1054  array<UserActionContext> contexts = {};
1055  vector tmp;
1056  array<IEntity> ents = handler.GetManualOverrideList(null, tmp);
1057  ActionsManagerComponent ac;
1058  array<UserActionContext> buff;
1059  UserActionContext ctx;
1060  array<BaseUserAction> actions;
1061  foreach (IEntity e : ents)
1062  {
1063  ac = ActionsManagerComponent.Cast(e.FindComponent(ActionsManagerComponent));
1064  if (!ac)
1065  continue;
1066 
1067  buff = {};
1068  int bc = ac.GetContextList(buff);
1069  for (int i = 0; i < bc; ++i)
1070  {
1071  ctx = buff[i];
1072  if (ctx.GetActionsCount() == 0)
1073  continue;
1074 
1075  actions = {};
1076  int actionsCount = ctx.GetActionsList(actions);
1077  foreach (BaseUserAction action : actions)
1078  {
1079  if (action.CanBeShown(GetCharacter()))
1080  {
1081  contexts.Insert(ctx);
1082  break;
1083  }
1084  }
1085  }
1086  }
1087 
1088  int nonEmptyCount = contexts.Count();
1089  m_iTargetContext = Math.Repeat(m_iTargetContext, nonEmptyCount);
1090 
1091  if (nonEmptyCount == 0)
1092  return 0.0;
1093 
1094  ctx = contexts[m_iTargetContext];
1095  vector contextPos = ctx.GetOrigin();
1096 
1097  vector localAimDirection = GetHeadAimingComponent().GetAimingDirection();
1098  vector targetDirection = contextPos - GetCharacter().EyePosition();
1099  vector localTargetDirection = GetCharacter().VectorToLocal( targetDirection );
1100  localTargetDirection.Normalize();
1101 
1102  float lookYaw = Math.Sin(localTargetDirection[0]) * Math.RAD2DEG;
1103  float lookPitch = Math.Sin(localTargetDirection[1]) * Math.RAD2DEG;
1104 
1105  //Shape shape = Shape.CreateSphere(COLOR_RED, ShapeFlags.ONCE | ShapeFlags.NOZBUFFER, contextPos, 0.01);
1106 
1107  lookPitch -= GetAimingComponent().GetAimingDirection()[1];
1108  targetAngles = Vector(lookYaw, lookPitch, 0) * Math.DEG2RAD;
1109 
1110  return 4.30 * Math.RAD2DEG ; // speed, approx deg/s
1111  }
1112 
1113  //------------------------------------------------------------------------------------------------
1115  SCR_ScriptedCharacterInputContext GetScrInputContext()
1116  {
1117  return m_pScrInputContext;
1118  }
1119 
1120  //------------------------------------------------------------------------------------------------
1127  void StartLoitering(int loiteringType, bool holsterWeapon, bool allowRootMotion, bool alignToPosition, vector targetPosition[4] = { "1 0 0", "0 1 0", "0 0 1", "0 0 0" })
1128  {
1130  return;
1131 
1132  SCR_CharacterCommandHandlerComponent scrCmdHandler = SCR_CharacterCommandHandlerComponent.Cast(GetCharacter().GetAnimationComponent().GetCommandHandler());
1133  if (!scrCmdHandler)
1134  return;
1135 
1136  if (scrCmdHandler.IsLoitering())
1137  return;
1138 
1139  m_pScrInputContext.m_iLoiteringType = loiteringType;
1140  m_pScrInputContext.m_iLoiteringShouldHolsterWeapon = holsterWeapon;
1141  m_pScrInputContext.m_bLoiteringShouldAlignCharacter = alignToPosition;
1142  m_pScrInputContext.m_mLoiteringPosition = targetPosition;
1143  m_pScrInputContext.m_bLoiteringRootMotion = allowRootMotion;
1144 
1145  if (IsGadgetInHands())
1146  RemoveGadgetFromHand(true);
1147 
1148  if (alignToPosition)
1149  AlignToPositionFromCurrentPosition(targetPosition);
1150 
1151  TryStartLoiteringInternal();
1152  }
1153 
1154  //------------------------------------------------------------------------------------------------
1155  protected bool AlignToPositionFromCurrentPosition(vector targetPosition[4], float toleranceXZ = 0.01, float toleranceY = 0.01)
1156  {
1158  return false;
1159 
1160  vector currentTransform[4];
1161  GetCharacter().GetWorldTransform(currentTransform);
1162  CharacterHeadingAnimComponent headingComponent = GetAnimationComponent().GetHeadingComponent();
1163  if (headingComponent)
1164  headingComponent.AlignPosDirWS(currentTransform[3], currentTransform[2], targetPosition[3], targetPosition[2]);
1165 
1166  return vector.DistanceSqXZ(currentTransform[3], targetPosition[3]) < (toleranceXZ * toleranceXZ)
1167  && Math.AbsFloat(currentTransform[3][2] - targetPosition[3][2]) < toleranceY;
1168  }
1169 
1170  //------------------------------------------------------------------------------------------------
1171  [RplRpc(RplChannel.Reliable, RplRcver.Server)]
1172  protected void Rpc_StartLoitering_S(int loiteringType, bool holsterWeapon, bool allowRootMotion, bool alignToPosition, vector targetPosition[4])
1173  {
1174  m_pScrInputContext.m_iLoiteringType = loiteringType;
1175  m_pScrInputContext.m_iLoiteringShouldHolsterWeapon = holsterWeapon;
1176  m_pScrInputContext.m_bLoiteringShouldAlignCharacter = alignToPosition;
1177  m_pScrInputContext.m_mLoiteringPosition = targetPosition;
1178  m_pScrInputContext.m_bLoiteringRootMotion = allowRootMotion;
1179 
1180  SCR_CharacterCommandHandlerComponent scrCmdHandler = SCR_CharacterCommandHandlerComponent.Cast(GetCharacter().GetAnimationComponent().GetCommandHandler());
1181  scrCmdHandler.StartCommandLoitering();
1182  }
1183 
1184  //------------------------------------------------------------------------------------------------
1185  protected bool TryStartLoiteringInternal()
1186  {
1187  CharacterHeadingAnimComponent headingComponent = GetAnimationComponent().GetHeadingComponent();
1188  if (IsChangingItem())
1189  return false;
1190 
1191  if (GetScrInputContext().m_iLoiteringShouldHolsterWeapon && GetCurrentItemInHands() != null)
1192  {
1193  TryEquipRightHandItem(null, EEquipItemType.EEquipTypeUnarmedContextual);
1194  return false;
1195  }
1196 
1197  if (headingComponent && headingComponent.IsAligning())
1198  {
1199  if (AlignToPositionFromCurrentPosition(GetScrInputContext().m_mLoiteringPosition, 0.02, 0.3)) // distance smaller than 2cm
1200  return false;
1201  }
1202 
1203  SCR_CharacterCommandHandlerComponent scrCmdHandler = SCR_CharacterCommandHandlerComponent.Cast(GetCharacter().GetAnimationComponent().GetCommandHandler());
1204  scrCmdHandler.StartCommandLoitering();
1205 
1207  Rpc(Rpc_StartLoitering_S,
1208  m_pScrInputContext.m_iLoiteringType,
1209  m_pScrInputContext.m_iLoiteringShouldHolsterWeapon,
1210  m_pScrInputContext.m_bLoiteringRootMotion,
1211  m_pScrInputContext.m_bLoiteringShouldAlignCharacter,
1212  m_pScrInputContext.m_mLoiteringPosition);
1213 
1214  return true;
1215  }
1216 
1217  //------------------------------------------------------------------------------------------------
1220  [RplRpc(RplChannel.Reliable, RplRcver.Server)]
1221  void RPC_StopLoitering_S(bool terminateFast)
1222  {
1224  Print("Called RPC_StopLoitering_S on a proxy.", LogLevel.ERROR);
1225 
1226  SCR_CharacterCommandHandlerComponent scrCmdHandler = SCR_CharacterCommandHandlerComponent.Cast(GetCharacter().GetAnimationComponent().GetCommandHandler());
1227  scrCmdHandler.StopLoitering(terminateFast);
1228  }
1229 
1230  //------------------------------------------------------------------------------------------------
1233  //terminateFast should be true when we are going into alerted or combat state.
1234  void StopLoitering(bool terminateFast)
1235  {
1237  return;
1238 
1239  SCR_CharacterCommandHandlerComponent scrCmdHandler = SCR_CharacterCommandHandlerComponent.Cast(GetCharacter().GetAnimationComponent().GetCommandHandler());
1240  scrCmdHandler.StopLoitering(terminateFast);
1241 
1243  Rpc(RPC_StopLoitering_S, terminateFast);
1244  }
1245 
1246  //------------------------------------------------------------------------------------------------
1247  bool IsLoitering()
1248  {
1249  SCR_CharacterCommandHandlerComponent handler = SCR_CharacterCommandHandlerComponent.Cast(GetAnimationComponent().GetCommandHandler());
1250  if (!handler)
1251  return false;
1252  else
1253  return handler.IsLoitering();
1254  }
1255 }
1256 
1257 enum ECharacterGestures // TODO: SCR_
1258 {
1259  NONE = 0,
1260  POINT_WITH_FINGER = 1
1261 }
IsFalling
proto external bool IsFalling()
ComponentEditorProps
SCR_FragmentEntityClass ComponentEditorProps
IsWeaponRaised
proto external bool IsWeaponRaised()
GetCurrentItemInHands
proto external IEntity GetCurrentItemInHands()
BaseTriggerComponent
Definition: BaseTriggerComponent.c:12
IsOwner
protected bool IsOwner()
Definition: SCR_SpawnRequestComponent.c:86
direction
vector direction
Definition: SCR_DestructibleTreeV2.c:31
SCR_VehicleFactionAffiliationComponent
Definition: SCR_VehicleFactionAffiliationComponent.c:6
SCR_ScriptedCharacterInputContext
Definition: SCR_ScriptedCharacterInputContext.c:1
SCR_PlayerController
Definition: SCR_PlayerController.c:31
SCR_MeleeWeaponProperties
Definition: SCR_MeleeWeaponProperties.c:7
OnItemUseFinished
func OnItemUseFinished
Definition: SCR_CharacterControllerComponent.c:32
GetInspectEntity
proto external IEntity GetInspectEntity()
GetAimingComponent
CharacterControllerComponentClass PrimaryControllerComponentClass GetAimingComponent()
GetCurrentMovementPhase
proto external int GetCurrentMovementPhase()
GetMovementInput
proto external vector GetMovementInput()
ECharacterLifeState
ECharacterLifeState
Definition: ECharacterLifeState.c:12
SCR_WeaponLib
Definition: WeaponLib.c:6
GetDynamicSpeed
proto external float GetDynamicSpeed()
Turret
@ Turret
Definition: SCR_AIVehicleBehavior.c:5
EMovementType
EMovementType
Definition: EMovementType.c:12
ScriptInvokerFloat2
ScriptInvokerBase< ScriptInvokerFloat2Method > ScriptInvokerFloat2
Definition: SCR_ScriptInvokerHelper.c:59
ECharacterStance
ECharacterStance
Definition: ECharacterStance.c:12
GetStance
proto external ECharacterStance GetStance()
Returns the current stance of the character.
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
OnPlayerDeathWithParamInvoker
ScriptInvokerBase< OnPlayerDeathWithParam > OnPlayerDeathWithParamInvoker
Definition: SCR_CharacterControllerComponent.c:9
ItemUseParameters
Definition: ItemUseParameters.c:15
CanJumpOutVehicleScript
event bool CanJumpOutVehicleScript()
Override to handle whether character can eject from vehicle via JumpOut input action.
Definition: CharacterControllerComponent.c:403
EEquipItemType
EEquipItemType
Definition: EEquipItemType.c:12
GetInventoryStorageManager
proto external InventoryStorageManagerComponent GetInventoryStorageManager()
StopDeployment
proto external void StopDeployment()
GetVelocity
proto external vector GetVelocity()
desc
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
Definition: SCR_RespawnBriefingComponent.c:17
IsInThirdPersonView
proto external bool IsInThirdPersonView()
RplRpc
SCR_AchievementsHandlerClass ScriptComponentClass RplRpc(RplChannel.Reliable, RplRcver.Owner)] void UnlockOnClient(AchievementId achievement)
Definition: SCR_AchievementsHandler.c:11
GetRplComponent
RplComponent GetRplComponent()
Returns the replication component associated to this entity.
Definition: SCR_RespawnComponent.c:200
func
func
Definition: SCR_AIThreatSystem.c:5
GetLifeState
proto external ECharacterLifeState GetLifeState()
GetInputContext
proto external CharacterInputContext GetInputContext()
SCR_CharacterControllerComponent
Definition: SCR_CharacterControllerComponent.c:35
GetPlayerController
proto external PlayerController GetPlayerController()
Definition: SCR_PlayerDeployMenuHandlerComponent.c:307
Instigator
Definition: Instigator.c:6
IsGadgetInHands
proto external bool IsGadgetInHands()
Returns true if there is a gadget in hands.
GetHeadAimingComponent
proto external AimingComponent GetHeadAimingComponent()
Returns component which controls head aiming.
IsChangingItem
proto external bool IsChangingItem()
IsProxy
protected bool IsProxy()
Definition: SCR_CampaignBuildingCompositionComponent.c:456
GetDynamicStance
proto external float GetDynamicStance()
OnLifeStateChangedInvoker
ScriptInvokerBase< OnLifeStateChanged > OnLifeStateChangedInvoker
Definition: SCR_CharacterControllerComponent.c:18
GetCharacter
proto external SCR_ChimeraCharacter GetCharacter()
Returns the current controlled character.
GetAnimationComponent
proto external CharacterAnimationComponent GetAnimationComponent()
Returns component which has animations controlling logic.
Attribute
typedef Attribute
Post-process effect of scripted camera.
GetWeaponManagerComponent
proto external BaseWeaponManagerComponent GetWeaponManagerComponent()
OnItemUseEnded
func OnItemUseEnded
Definition: SCR_CharacterControllerComponent.c:27
SetBanking
proto external void SetBanking(float val)
GetCommandHandler
proto external CharacterCommandHandlerComponent GetCommandHandler()
command handler access
SCR_CharacterDamageManagerComponent
Definition: SCR_CharacterDamageManagerComponent.c:18
OnPlayerDeathWithParam
func OnPlayerDeathWithParam
Definition: SCR_CharacterControllerComponent.c:8
OnControlledByPlayer
func OnControlledByPlayer
Definition: SCR_CharacterControllerComponent.c:13
BaseWeaponComponent
Definition: BaseWeaponComponent.c:12
GetCanThrow
proto external bool GetCanThrow()
OnDiag
event protected void OnDiag(IEntity owner, float timeslice)
OnItemUseFinishedInvoker
ScriptInvokerBase< OnItemUseFinished > OnItemUseFinishedInvoker
Definition: SCR_CharacterControllerComponent.c:33
ShouldHoldInputForRoll
proto external bool ShouldHoldInputForRoll()
GetIsSprintingToggle
proto external bool GetIsSprintingToggle()
RemoveGadgetFromHand
proto external void RemoveGadgetFromHand(bool skipAnimations=false)
Remove held gadget.
SightsFOVInfo
Definition: SightsFOVInfo.c:11
GetMovementVelocity
proto external vector GetMovementVelocity()
GetDamageManager
proto external SCR_DamageManagerComponent GetDamageManager()
Returns component which handles damage.
m_CameraHandler
protected SCR_CharacterCameraHandlerComponent m_CameraHandler
Definition: SCR_InfoDisplayExtended.c:26
OnItemUseBegan
func OnItemUseBegan
Definition: SCR_CharacterControllerComponent.c:22
SetRoll
proto external void SetRoll(int val)
2 - right, 1 - left
GetOwner
IEntity GetOwner()
Owner entity of the fuel tank.
Definition: SCR_FuelNode.c:128
SCR_BaseVariableSightsFOVInfo
Definition: SCR_BaseVariableSightsFOVInfo.c:1
OnItemUseBeganInvoker
ScriptInvokerBase< OnItemUseBegan > OnItemUseBeganInvoker
Definition: SCR_CharacterControllerComponent.c:23
GrenadeMoveComponent
Definition: GrenadeMoveComponent.c:12
CompartmentUserAction
Definition: CompartmentUserAction.c:12
SCR_GarbageSystem
Script entry for garbage system modding.
Definition: SCR_GarbageSystem.c:2
m_MeleeComponent
protected SCR_MeleeComponent m_MeleeComponent
Definition: SCR_CharacterCommandHandler.c:119
CharacterCommandMove
CharacterCommandMove.
Definition: CharacterCommandMove.c:13
CanGetOutVehicleScript
event bool CanGetOutVehicleScript()
Override to handle whether character can get out of vehicle via GetOut input action.
Definition: CharacterControllerComponent.c:401
GetIsWeaponDeployed
proto external bool GetIsWeaponDeployed()
IsFreeLookEnabled
proto external bool IsFreeLookEnabled()
SetPartialLower
proto external void SetPartialLower(bool state)
Sets desired partial lower state, if allowed.
ScriptInvokerVoid
ScriptInvokerBase< ScriptInvokerVoidMethod > ScriptInvokerVoid
Definition: SCR_ScriptInvokerHelper.c:9
IsWeaponADS
proto external bool IsWeaponADS()
SetWeaponRaised
proto external void SetWeaponRaised(bool val)
Set the current weapon-raised state.
IsUsingItem
proto external bool IsUsingItem()
GetIsWeaponDeployedBipod
proto external bool GetIsWeaponDeployedBipod()
BaseUserAction
Definition: BaseUserAction.c:12
EDamageType
EDamageType
Definition: EDamageType.c:12
NONE
SCR_CharacterControllerComponent NONE
EWeaponType
EWeaponType
Definition: EWeaponType.c:12
IsDead
proto external bool IsDead()
params
Configs ServerBrowser KickDialogs params
Definition: SCR_NotificationSenderComponent.c:24
CanPartialLower
proto external bool CanPartialLower()
Returns true if the character can partially lower (weapon).
OnControlledByPlayerInvoker
ScriptInvokerBase< OnControlledByPlayer > OnControlledByPlayerInvoker
Definition: SCR_CharacterControllerComponent.c:14
TryEquipRightHandItem
proto external bool TryEquipRightHandItem(IEntity item, EEquipItemType type, bool swap=false, BaseUserAction callbackAction=null)
SCR_DebugMenuID
SCR_DebugMenuID
This enum contains all IDs for DiagMenu entries added in script.
Definition: DebugMenuID.c:3
IsSprinting
proto external bool IsSprinting()
IsClimbing
proto external bool IsClimbing()
OnLifeStateChanged
func OnLifeStateChanged
Definition: SCR_CharacterControllerComponent.c:17
UserActionContext
Definition: UserActionContext.c:15
CharacterControllerComponentClass
Definition: CharacterControllerComponent.c:12
SCR_CharacterControllerComponentClass
Definition: SCR_CharacterControllerComponent.c:2
OnItemUseEndedInvoker
ScriptInvokerBase< OnItemUseEnded > OnItemUseEndedInvoker
Definition: SCR_CharacterControllerComponent.c:28
SCR_MeleeComponent
Definition: SCR_MeleeComponent.c:23
GetCanFireWeapon
proto external bool GetCanFireWeapon()
category
params category
Definition: SCR_VehicleDamageManagerComponent.c:180
IsPartiallyLowered
proto external bool IsPartiallyLowered()
Returns true if the character is partially lowered.