Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_MortarMuzzleComponent.c
Go to the documentation of this file.
2{
3 [Attribute(desc: "Name of the action for which user will wait befor transfering the shell to the mortar - f.e. CharacterFire which is LMB")]
4 protected string m_sFireActionName;
5
6 [Attribute(desc: "Name of the signal that will be used to adjust the volume of the fired projectile based on the number of used charge rings")]
7 protected string m_sFirePowerSignalName;
8
9 [Attribute("45 85 0", desc: "Minimum (X) and maximum (Y) vertical angle for the mortar's muzzle")]
11
12 //------------------------------------------------------------------------------------------------
14 {
15 return m_sFireActionName;
16 }
17
18 //------------------------------------------------------------------------------------------------
20 {
22 }
23
24 //------------------------------------------------------------------------------------------------
29}
30
31class SCR_MortarMuzzleComponent : MortarMuzzleComponent
32{
33
34 [Attribute(desc: "Position and rotation that will be used to play animation of dropping the shell")]
35 protected ref PointInfo m_LoaderPosition;
37 [Attribute(desc: "Position and rotation that will be used to play animation of dropping the shell but from the left side")]
38 protected ref PointInfo m_LoaderPositionLeft;
41 protected SCR_MortarShellGadgetComponent m_ShellComponent;
43 protected AnimationEventID m_MortarFireEnd = -1;
44 protected AnimationEventID m_MortarFireReady = -1;
45 protected AnimationEventID m_MortarFireStart = -1;
46 protected bool m_bLoadedFromLeftSide;
47 protected bool m_bBeingLoaded;
48
49 protected const string ANIM_EVENT_NAME_FIRE = "MortarFireReady";
50 protected const string ANIM_EVENT_NAME_START = "MortarFireStart";
51 protected const string ANIM_EVENT_NAME_END = "Event_DetachCharacter";
52 protected const string ANIM_VARIABLE_FIRING = "Firing";
53 protected const string ANIM_VARIABLE_LEFT_SIDE = "IsLeftSide";
54 protected const string ANIM_BIND_COMMAND = "CMD_Item_Action";
55 protected const string ANIM_ENTRY_POINT = "FireMasterControl";
56 protected const string ANIM_BINDING_NAME = "Weapon";
58 //------------------------------------------------------------------------------------------------
59 override void OnPostInit(IEntity owner)
60 {
61 SetEventMask(owner, EntityEvent.INIT);
62 }
63
64 //------------------------------------------------------------------------------------------------
65 override void EOnInit(IEntity owner)
66 {
67 SCR_WeaponAttachmentsStorageComponent attachmentStorage = SCR_WeaponAttachmentsStorageComponent.Cast(owner.FindComponent(SCR_WeaponAttachmentsStorageComponent));
68 if (attachmentStorage)
69 attachmentStorage.m_OnItemAddedToSlotInvoker.Insert(OnShellLoaded);
70
71 if (m_LoaderPosition)
72 m_LoaderPosition.Init(owner);
73
74 if (m_LoaderPositionLeft)
75 m_LoaderPositionLeft.Init(owner);
76
78 if (muzzleEffectComp)
79 muzzleEffectComp.GetOnWeaponFired().Insert(OnWeaponFired);
80
82 }
83
84 //------------------------------------------------------------------------------------------------
86 {
87 return m_bBeingLoaded;
88 }
89
90 //------------------------------------------------------------------------------------------------
91 void SetLoadingState(bool newState)
92 {
93 m_bBeingLoaded = newState;
94 }
95
96 //------------------------------------------------------------------------------------------------
98 {
99 BaseWeaponManagerComponent weaponManager = m_TurretController.GetWeaponManager();
100 if (!weaponManager)
101 return vector.Zero;
102
103 vector transform[4];
104 weaponManager.GetCurrentMuzzleTransform(transform);
105 return transform[2];
106 }
107
108 //------------------------------------------------------------------------------------------------
110 {
111 return GetMuzzleDirection().VectorToAngles()[1];
112 }
113
114 //------------------------------------------------------------------------------------------------
118 void OnShellLoaded(IEntity item, int slotID)
119 {
120 if (!item)
121 return;
122
123 SCR_MortarShellGadgetComponent shellGadget = SCR_MortarShellGadgetComponent.Cast(item.FindComponent(SCR_MortarShellGadgetComponent));
124 if (!shellGadget)
125 return;
126
127 SoundComponent soundComp = SoundComponent.Cast(GetOwner().FindComponent(SoundComponent));
128 if (!soundComp)
129 return;
130
131 soundComp.SoundEvent(SCR_SoundEvent.SOUND_LOAD);
132 }
133
134 //------------------------------------------------------------------------------------------------
140 void LoadShell(notnull SCR_MortarShellGadgetComponent shellComp, notnull ChimeraCharacter character, float fuzeTime = -1, bool fromLeftSide = false)
141 {
142 m_CharController = SCR_CharacterControllerComponent.Cast(character.GetCharacterController());
143 if (!m_CharController)
144 return;
145
147 if (!data)
148 return;
149
150 if (!m_CharController.CanPlayItemGesture())
151 return;
152
153 if (shellComp.IsUsingTimeFuze())
154 {
155 if (fuzeTime >= 0)
156 {
157 shellComp.SetFuzeTime(fuzeTime);
158 }
159 else
160 {
161 float elevation = GetMuzzleElevation();
162 float timeToDetonation = shellComp.GetTimeToDetonation(elevation, false);
163 shellComp.SetFuzeTime(timeToDetonation);
164 }
165 }
166
167 SCR_WeaponBlastComponent weaponBlastComponent = SCR_WeaponBlastComponent.Cast(GetOwner().FindComponent(SCR_WeaponBlastComponent));
168 if (weaponBlastComponent)
169 weaponBlastComponent.OverrideInstigator(character);
170
172 if (!data.GetFirePowerSignalName().IsEmpty() && signalsMgr)
173 {
174 int signalId = signalsMgr.AddOrFindSignal(data.GetFirePowerSignalName()); // if such signal does not exist then we need to create it for long range sound replication to work properly
175 if (signalId > -1)
176 signalsMgr.SetSignalValue(signalId, shellComp.GetCurentChargeRingConfig()[0]);
177 }
178
179 m_bBeingLoaded = true;
180
181 bool isAi;
182 if (!SCR_CharacterHelper.IsPlayerOrAIOwner(character, isAi))
183 {
184 shellComp.SetLoadedState(true, this);
185 m_bLoadedFromLeftSide = fromLeftSide;
186 m_MortarFireStart = GameAnimationUtils.RegisterAnimationEvent(ANIM_EVENT_NAME_START);
187 m_CharController.GetOnAnimationEvent().Insert(OnAnimationEvent);
188 return;//reject those who arent in control of the loader but do it only now to inform them of who did it
189 }
190
191 m_MortarFireStart = -1;//clear it to ensure that loader doesnt try to reset the animation attributes
192 CharacterAnimationComponent animationComponent = m_CharController.GetAnimationComponent();
193 if (!animationComponent)
194 return;
195
196 if (isAi)
197 {
198 RplComponent loaderRplComp = character.GetRplComponent();
199 if (!loaderRplComp)
200 return;
201
202 RplComponent shellRplComp = SCR_EntityHelper.GetEntityRplComponent(shellComp.GetOwner());
203 if (!shellRplComp)
204 return;
205
206 //Because AI is not broadcasting their user action usage this has to be done manually for them
207 Rpc(SynchronizeLoaderData, loaderRplComp.Id(), shellRplComp.Id(), shellComp.GetFuzeTime(), fromLeftSide);
208 }
209
210 m_ShellComponent = shellComp;
211
212 m_MortarFireReady = GameAnimationUtils.RegisterAnimationEvent(ANIM_EVENT_NAME_FIRE);
213 m_MortarFireEnd = GameAnimationUtils.RegisterAnimationEvent(ANIM_EVENT_NAME_END);
214 int itemActionId = animationComponent.BindCommand(ANIM_BIND_COMMAND);
215
217 animParams.SetEntity(GetOwner());
218 if (fromLeftSide)
219 animParams.SetAlignmentPoint(m_LoaderPositionLeft);
220 else
221 animParams.SetAlignmentPoint(m_LoaderPosition);
222
223 animParams.SetAllowMovementDuringAction(false);
224 animParams.SetKeepInHandAfterSuccess(false);
225 animParams.SetKeepGadgetVisible(true);
226 animParams.SetIsMainUserOfTheItem(false);
227 animParams.SetCommandID(itemActionId);
228 animParams.SetItemGraphEntryPoint(ANIM_ENTRY_POINT);
229 animParams.SetCharGraphBindingName(ANIM_BINDING_NAME);
230 if (m_CharController.TryUseItemOverrideParams(animParams))
231 {
233 m_CharController.GetOnAnimationEvent().Insert(OnAnimationEvent);
234 m_CharController.m_OnItemUseEndedInvoker.Insert(OnAnimationEnded);
235 }
236 else
237 {
239 }
240 }
241
242 //------------------------------------------------------------------------------------------------
246 protected void SetAnimationAttributes(notnull CharacterControllerComponent controller, bool loadedFromLeftSide)
247 {
248 CharacterAnimationComponent animationComponent = controller.GetAnimationComponent();
249 if (!animationComponent)
250 return;
251
253 if (!data)
254 return;
255
256 const vector angleLimit = data.GetVerticalAngleLimits();
257 float elevation = Math.Clamp(GetMuzzleElevation(), angleLimit[0], angleLimit[1]);
258 animationComponent.SetAnimAimY(elevation);
259
260 TAnimGraphVariable varId = animationComponent.BindVariableBool(ANIM_VARIABLE_LEFT_SIDE);
261 if (varId >= 0)
262 animationComponent.SetSharedVariableBool(varId, loadedFromLeftSide, true);
263 }
264
265 //------------------------------------------------------------------------------------------------
270 void OnWeaponFired(IEntity effectEntity, BaseMuzzleComponent muzzle, IEntity projectileEntity)
271 {
272 m_bBeingLoaded = false;
274 if (animationComponent)
275 {
276 TAnimGraphVariable varId = animationComponent.BindBoolVariable(ANIM_VARIABLE_FIRING);
277 animationComponent.SetBoolVariable(varId, true);
278 GetGame().GetCallqueue().CallLater(ResetRecoilAnimationVariable, 50, param1: varId); //delyaed to allow the animation system to see the change of the value
279 }
280
281 if (!projectileEntity)
282 return;
283
284 SCR_MortarShellGadgetComponent shellComp = SCR_MortarShellGadgetComponent.Cast(projectileEntity.FindComponent(SCR_MortarShellGadgetComponent));
285 if (shellComp)
286 shellComp.OnShellFired(this);
287
288 if (!m_CharController)
289 return;
290
292 if (!blamedCharacter)
293 return;
294
295 BaseProjectileComponent projectileComp = BaseProjectileComponent.Cast(projectileEntity.FindComponent(BaseProjectileComponent));
296 if (!projectileComp)
297 return;
298
299 projectileComp.GetInstigator().SetInstigator(blamedCharacter);
300 }
301
302 //------------------------------------------------------------------------------------------------
307 {
308 ChimeraCharacter blamedCharacter = ChimeraCharacter.Cast(controller.GetOwner());
309 if (!blamedCharacter)
310 return null;
311
312 AIControlComponent aiControlComp = controller.GetAIControlComponent();
313 if (!aiControlComp)
314 return blamedCharacter;
315
316 AIAgent agent = aiControlComp.GetControlAIAgent();
317 SCR_AIGroup group = SCR_AIGroup.Cast(agent);
318 if (!group && agent)
319 group = SCR_AIGroup.Cast(agent.GetParentGroup());
320
321 if (!group)
322 return blamedCharacter;
323
324 SCR_AIWaypointArtillerySupport currentWaypoint = SCR_AIWaypointArtillerySupport.Cast(group.GetCurrentWaypoint());
325 if (!currentWaypoint)
326 return blamedCharacter;
327
328 int playerId = group.GetFirstPlayerLeaderID();
329 if (playerId > 0)//make SL responsible for all kills if he ordered the AI to fire the mortar
330 blamedCharacter = ChimeraCharacter.Cast(GetGame().GetPlayerManager().GetPlayerControlledEntity(playerId));
331
332 return blamedCharacter;
333 }
334
335 //------------------------------------------------------------------------------------------------
338 {
340 if (!animationComponent)
341 return;
342
343 animationComponent.SetBoolVariable(varId, false);
344 }
345
346 //------------------------------------------------------------------------------------------------
354 protected void OnAnimationEvent(AnimationEventID animEventType, AnimationEventID animUserString, int intParam, float timeFromStart, float timeToEnd, SCR_CharacterControllerComponent controller)
355 {
356 if (m_CharController && animEventType == m_MortarFireStart)
357 {
358 SetAnimationAttributes(m_CharController, m_bLoadedFromLeftSide);
359 m_CharController.GetOnAnimationEvent().Remove(OnAnimationEvent);
360 }
361
362 if (animEventType == m_MortarFireEnd && controller)
363 {
364 CharacterAnimationComponent animationComponent = controller.GetAnimationComponent();
365 if (!animationComponent)
366 return;
367
368 CharacterCommandHandlerComponent commandHandler = animationComponent.GetCommandHandler();
369 if (commandHandler)
370 commandHandler.FinishItemUse(false);
371
373 {
374 CameraHandlerComponent cameraHandler = m_CharController.GetCameraHandlerComponent();
375 if (cameraHandler)
376 {
378 ScriptedCameraItem camera = cameraHandler.GetCurrentCamera();
379 if (camera && camera.GetOverrideDirectBoneMode() != 0)
380 camera.OverrideDirectBoneMode(0);
381 }
382 }
383
384 return;
385 }
386
387 if (!m_ShellComponent)
388 return;
389
390 if (animEventType != m_MortarFireReady)
391 return;
392
393 IEntity owner;
395 owner = m_CharController.GetOwner();
396
398 if (!data)
399 return;
400
401 if (data && m_ShellComponent.SetLoadedState(true, this, data.GetFireActionName(), owner))
402 m_ShellComponent.GetOnShellUsed().Insert(TransferShellToMortar);
403 else
405
407 if (m_CharController && !m_CharController.IsInThirdPersonView())
408 {
409 CameraHandlerComponent cameraHandler = m_CharController.GetCameraHandlerComponent();
410 if (cameraHandler)
411 {
412 ScriptedCameraItem camera = cameraHandler.GetCurrentCamera();
413 if (camera && camera.GetOverrideDirectBoneMode() == 0)
414 {
415 vector aimingAngles = m_CharController.GetInputContext().GetAimingAngles();
416 m_CharController.GetInputContext().SetAimingAngles(Vector(aimingAngles[0], 0, 0));
417 camera.OverrideDirectBoneMode(EDirectBoneMode.RelativeTransform);
418 }
419 }
420 }
421 }
422
423 //------------------------------------------------------------------------------------------------
426 protected void TransferShellToMortar()
427 {
428 if (!m_ShellComponent)
429 return;
430
431 m_ShellComponent.GetOnShellUsed().Remove(TransferShellToMortar);
432 m_ShellComponent.UpdateVisibility(m_ShellComponent.GetMode());
433 m_ShellComponent.SetLoadedState(false);
434
435 if (!m_CharController)
436 return;
437
438 SCR_InventoryStorageManagerComponent playerInventory = SCR_InventoryStorageManagerComponent.Cast(m_CharController.GetInventoryStorageManager());
439 if (!playerInventory)
440 return;
441
442 SCR_WeaponAttachmentsStorageComponent weaponAttachmentStorage = SCR_WeaponAttachmentsStorageComponent.Cast(GetOwner().FindComponent(SCR_WeaponAttachmentsStorageComponent));
443 if (!weaponAttachmentStorage)
444 return;
445
446 SCR_InvEquipAnyItemCB inventoryCallBack = new SCR_InvEquipAnyItemCB();
447 IEntity shellEntity = m_ShellComponent.GetOwner();
448 if (shellEntity)
449 playerInventory.TryAssigningNextItemToQuickSlot(shellEntity, equipCallback: inventoryCallBack, equipNewItem: true);
450
451 playerInventory.TryMoveItemToStorage(shellEntity, weaponAttachmentStorage, cb: inventoryCallBack);
452 m_ShellComponent = null;
453
454 CharacterAnimationComponent animationComponent = m_CharController.GetAnimationComponent();
455 if (!animationComponent)
456 return;
457
458 TAnimGraphVariable varId = animationComponent.BindVariableBool(ANIM_VARIABLE_FIRING);
459 //inform animation graph of used by the loader that charater loaded the shell to the mortar
460 animationComponent.SetVariableBool(varId, true);
461 }
462
463 //------------------------------------------------------------------------------------------------
468 protected void OnAnimationEnded(IEntity item, bool successful, ItemUseParameters animParams)
469 {
470 m_bBeingLoaded = false;
471 if (!m_CharController)
472 return;
473
474 m_CharController.GetOnAnimationEvent().Remove(OnAnimationEvent);
475 m_CharController.m_OnItemUseEndedInvoker.Remove(OnAnimationEnded);
476
477 CameraHandlerComponent cameraHandler = m_CharController.GetCameraHandlerComponent();
478 if (cameraHandler)
479 {
480 ScriptedCameraItem camera = cameraHandler.GetCurrentCamera();
481 if (camera && camera.GetOverrideDirectBoneMode() != 0)
482 {
483 camera.OverrideDirectBoneMode(0);
484 }
485 }
486
487 if (!m_ShellComponent)
488 return;
489
490 m_ShellComponent.GetOnShellUsed().Remove(TransferShellToMortar);
491 m_ShellComponent.UpdateVisibility(m_ShellComponent.GetMode());
492 m_ShellComponent.ToggleActive(false, SCR_EUseContext.CUSTOM);
493 m_ShellComponent.SetLoadedState(false);
494 m_ShellComponent = null;
495 }
496
497 //------------------------------------------------------------------------------------------------
498 [RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
499 protected void SynchronizeLoaderData(RplId loaderRplId, RplId shellRplId, float fuseTime, bool loadedFromLeftSide)
500 {
501 RplComponent loaderRplComp = RplComponent.Cast(Replication.FindItem(loaderRplId));
502 if (!loaderRplComp)
503 return;
504
505 RplComponent shellRplComp = RplComponent.Cast(Replication.FindItem(shellRplId));
506 if (!shellRplComp)
507 return;
508
509 ChimeraCharacter loader = ChimeraCharacter.Cast(loaderRplComp.GetEntity());
510 if (!loader)
511 return;
512
513 IEntity shell = shellRplComp.GetEntity();
514 if (!shell)
515 return;
516
517 m_CharController = SCR_CharacterControllerComponent.Cast(loader.GetCharacterController());
518 if (!m_CharController)
519 return;
520
521 SCR_MortarShellGadgetComponent mortarShellComp = SCR_MortarShellGadgetComponent.Cast(shell.FindComponent(SCR_MortarShellGadgetComponent));
522 if (!mortarShellComp)
523 return;
524
525 mortarShellComp.SetFuzeTime(fuseTime);
526 mortarShellComp.SetLoadedState(true, this);
527 m_bBeingLoaded = true;
528 SetAnimationAttributes(m_CharController, loadedFromLeftSide);
529 }
530}
int AnimationEventID
int TAnimGraphVariable
Definition ECommandIDs.c:2
ArmaReforgerScripted GetGame()
Definition game.c:1398
SCR_CharacterSoundComponentClass GetComponentData()
SCR_CharacterControllerComponent m_CharController
void OnAnimationEnded(IEntity item, bool successful, ItemUseParameters animParams)
SCR_EUseContext
Get all prefabs that have the spawner data
void SetAnimationAttributes(notnull CharacterControllerComponent controller, bool loadedFromLeftSide)
vector GetMuzzleDirection()
bool IsBeingLoaded()
void OnShellLoaded(IEntity item, int slotID)
ChimeraCharacter FindResponsibleCharacter(notnull SCR_CharacterControllerComponent controller)
void ResetRecoilAnimationVariable(TAnimGraphVariable varId)
Method used to reset the animation variable to its default value.
void LoadShell(notnull SCR_MortarShellGadgetComponent shellComp, notnull ChimeraCharacter character, float fuzeTime=-1, bool fromLeftSide=false)
void TransferShellToMortar()
void SynchronizeLoaderData(RplId loaderRplId, RplId shellRplId, float fuseTime, bool loadedFromLeftSide)
float GetMuzzleElevation()
void SetLoadingState(bool newState)
func OnWeaponFired
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
TurretControllerComponent m_TurretController
EDirectBoneMode
proto external int SetEventMask(notnull IEntity owner, int mask)
void Rpc(func method, void p0=NULL, void p1=NULL, void p2=NULL, void p3=NULL, void p4=NULL, void p5=NULL, void p6=NULL, void p7=NULL)
proto external Managed FindComponent(typename typeName)
Definition Math.c:13
PointInfo - allows to define position.
Definition PointInfo.c:9
Main replication API.
Definition Replication.c:14
Replication item identifier.
Definition RplId.c:14
int GetFirstPlayerLeaderID()
static RplComponent GetEntityRplComponent(notnull IEntity entity)
OnItemWeaponFiredInvoker GetOnWeaponFired()
IEntity GetOwner()
Owner entity of the fuel tank.
override void EOnInit(IEntity owner)
event void OnAnimationEvent(AnimationEventID animEventType, AnimationEventID animUserString, int intParam, float timeFromStart, float timeToEnd)
SCR_FieldOfViewSettings Attribute
EntityEvent
Various entity events.
Definition EntityEvent.c:14
void RplRpc(RplChannel channel, RplRcver rcver, RplCondition condition=RplCondition.None, string customConditionName="")
Definition EnNetwork.c:95
RplRcver
Definition RplRcver.c:59
RplChannel
Communication channel. Reliable is guaranteed to be delivered. Unreliable not.
Definition RplChannel.c:14
Tuple param1
proto native vector Vector(float x, float y, float z)