DayZ Scripts
v1.21.156300 ยท Jun 20, 2023
 
Loading...
Searching...
No Matches
WeaponManager.c
Go to the documentation of this file.
2{
4
6
7 protected int m_LastAcknowledgmentID;
8
10 protected Magazine m_PendingTargetMagazine;
12 protected int m_PendingWeaponAction;
14
15 protected bool m_canEnd;
16 protected bool m_justStart;
17 protected bool m_InProgress;
18 protected bool m_IsEventSended;
19 protected bool m_WantContinue;
20 protected bool m_InIronSight;
21 protected bool m_InOptic;
22 protected bool m_readyToStart;
24 protected MagazineStorage m_MagazineInHand;
27
28 protected const int FORCE_EJECT_BULLET_TIMEOUT = 2000;
29#ifdef DIAG_DEVELOPER
30 protected int m_BurstOption;
31#endif
32 //Reload
36 protected Magazine m_PreparedMagazine;
37
38 //Jamming
39 protected float m_NewJamChance;
40 protected bool m_WaitToSyncJamChance;
41
42
44
46 {
48 m_player = player;
52 m_WeaponInHand = NULL;
53 m_MagazineInHand = NULL;
54 m_ControlAction = NULL;
57 m_InProgress = false;
58 m_WantContinue = true;
59 m_IsEventSended = false;
60 m_canEnd = false;
61 m_readyToStart = false;
63
64 m_NewJamChance = -1;
66
70 m_PreparedMagazine = null;
71
72#ifdef DEVELOPER
73 m_BurstOption = 0;
74#endif
75 }
76//----------------------------------------------------------------------------
77// Weapon Action conditions
78//----------------------------------------------------------------------------
80 {
81 if( m_player.GetHumanInventory().GetEntityInHands() != wpn )
82 return false;
83
84 if( m_player.IsLiftWeapon() || !m_player.IsRaised() || wpn.IsDamageDestroyed() || m_player.GetDayZPlayerInventory().IsProcessing() || !m_player.IsWeaponRaiseCompleted() || m_player.IsFighting() )
85 return false;
86
87 return true;
88
89 }
90
91
92 bool CanAttachMagazine(Weapon_Base wpn, Magazine mag, bool reservationCheck = true )
93 {
94 if ( !wpn || !mag )
95 return false;
96
97 if ( m_player.GetHumanInventory().GetEntityInHands() != wpn )
98 return false;
99
100 if ( wpn.IsDamageDestroyed())
101 return false;
102
103 //if ( mag.GetHierarchyRootPlayer() && mag.GetHierarchyRootPlayer() != m_player )
104 //return false;
105
106 if( m_player.IsItemsToDelete())
107 return false;
108
109 if ( reservationCheck && (m_player.GetInventory().HasInventoryReservation(wpn, null) || m_player.GetInventory().HasInventoryReservation(mag, null)))
110 return false;
111
112 InventoryLocation invLoc;
113 invLoc = new InventoryLocation();
114
115 mag.GetInventory().GetCurrentInventoryLocation(invLoc);
116 Weapon_Base wnp2;
117
118
119 //magazine is already in weapon
120 if ( Class.CastTo(wnp2, invLoc.GetParent()) )
121 return false;
122
123 int muzzleIndex = wpn.GetCurrentMuzzle();
124
125 if (wpn.CanAttachMagazine(muzzleIndex, mag))
126 return true;
127
128 return false;
129
130 }
131//---------------------------------------------------------------------------
132
133 bool CanSwapMagazine(Weapon_Base wpn, Magazine mag, bool reservationCheck = true)
134 {
135 if ( !wpn || !mag )
136 return false;
137
138 if ( m_player.GetHumanInventory().GetEntityInHands() != wpn )
139 return false;
140
141 if ( mag.IsDamageDestroyed() || wpn.IsDamageDestroyed())
142 return false;
143
144 //if ( mag.GetHierarchyRootPlayer() && mag.GetHierarchyRootPlayer() != m_player )
145 //return false;
146
147 if( m_player.IsItemsToDelete())
148 return false;
149
150 if ( reservationCheck && (m_player.GetInventory().HasInventoryReservation(wpn, null) || m_player.GetInventory().HasInventoryReservation(mag, null)))
151 return false;
152
153
154 InventoryLocation invLoc;
155 invLoc = new InventoryLocation();
156
157 mag.GetInventory().GetCurrentInventoryLocation(invLoc);
158 Weapon_Base wnp2;
159
160 //second magazine is already in weapon
161 if( Class.CastTo(wnp2, invLoc.GetParent()) )
162 return false;
163
164 int muzzleIndex = wpn.GetCurrentMuzzle();
165
166 Magazine mag2;
167 if( !Class.CastTo(mag2, wpn.GetMagazine(muzzleIndex)) )
168 return false;
169
170 if( GameInventory.CanSwapEntitiesEx( mag, mag2 ) )
171 return true;
172
174
175 if( GameInventory.CanForceSwapEntitiesEx( mag, null, mag2, il ) )
176 return true;
177
178 return false;
179 }
180//----------------------------------------------------------------------------
181 bool CanDetachMagazine(Weapon_Base wpn, Magazine mag, bool reservationCheck = true)
182 {
183 if ( !wpn || !mag )
184 return false;
185
186 if ( m_player.GetHumanInventory().GetEntityInHands() != wpn )
187 return false;
188
189 if ( mag.GetHierarchyParent() != wpn )
190 return false;
191
192 if( m_player.IsItemsToDelete())
193 return false;
194
195 if ( reservationCheck && (m_player.GetInventory().HasInventoryReservation(wpn, null) || m_player.GetInventory().HasInventoryReservation(mag, null)))
196 return false;
197
198 return true;
199 }
200//---------------------------------------------------------------------------
201 bool CanLoadBullet(Weapon_Base wpn, Magazine mag, bool reservationCheck = true)
202 {
203 if (!wpn || !mag)
204 return false;
205
206 if (m_player.GetHumanInventory().GetEntityInHands() != wpn)
207 return false;
208
209 if (mag.IsDamageDestroyed() || wpn.IsDamageDestroyed())
210 return false;
211
212 if (wpn.IsJammed())
213 return false;
214
215 if (m_player.IsItemsToDelete())
216 return false;
217
218 if (reservationCheck && (m_player.GetInventory().HasInventoryReservation(wpn, null) || m_player.GetInventory().HasInventoryReservation(mag, null)))
219 return false;
220
221 for (int i = 0; i < wpn.GetMuzzleCount(); i++)
222 {
223 if (wpn.CanChamberBullet(i, mag))
224 return true;
225 }
226
227 return false;
228 }
229//---------------------------------------------------------------------------
230 bool CanUnjam(Weapon_Base wpn, bool reservationCheck = true)
231 {
232 if( !wpn )
233 return false;
234
235 if( m_player.GetHumanInventory().GetEntityInHands() != wpn)
236 return false;
237
238 if( wpn.IsDamageDestroyed())
239 return false;
240
241 if( m_player.IsItemsToDelete())
242 return false;
243
244 if ( reservationCheck && m_player.GetInventory().HasInventoryReservation(wpn, null))
245 return false;
246
247
248 if( !wpn.IsJammed(/*wpn.GetCurrentMuzzle()*/) )
249 return false;
250
251 return true;
252 }
253
254 bool CanEjectBullet(Weapon_Base wpn, bool reservationCheck = true)
255 {
256 if( !wpn )
257 return false;
258
259 if( m_player.GetHumanInventory().GetEntityInHands() != wpn)
260 return false;
261
262 if( m_player.IsItemsToDelete())
263 return false;
264
265 if( reservationCheck && m_player.GetInventory().HasInventoryReservation(wpn, null))
266 return false;
267
268 if( !wpn.CanEjectBullet() )
269 return false;
270
271 if( wpn.IsJammed(/*wpn.GetCurrentMuzzle()*/) )
272 return false;
273
274 return true;
275 }
276
278 {
280 }
281//----------------------------------------------------------------------------
282 bool InventoryReservation( Magazine mag, InventoryLocation invLoc)
283 {
284 Weapon_Base weapon;
285 InventoryLocation ilWeapon = new InventoryLocation();
286 if (Weapon_Base.CastTo(weapon, m_player.GetItemInHands()) )
287 {
288 weapon.GetInventory().GetCurrentInventoryLocation(ilWeapon);
289 if ( m_player.GetInventory().HasInventoryReservation(weapon, ilWeapon) )
290 {
291 return false;
292 }
293 else
294 {
295 m_player.GetInventory().AddInventoryReservationEx(weapon,ilWeapon,GameInventory.c_InventoryReservationTimeoutMS);
296 }
297 }
298
299 if( invLoc )
300 {
301 if ( m_player.GetInventory().HasInventoryReservation(invLoc.GetItem(),invLoc) )
302 {
303 m_player.GetInventory().ClearInventoryReservationEx(weapon, ilWeapon);
304 return false;
305 }
306 else
307 {
308 m_player.GetInventory().AddInventoryReservationEx(invLoc.GetItem(),invLoc,GameInventory.c_InventoryReservationTimeoutMS);
309 }
310 }
311
312 if( mag )
313 {
316
317 if ( m_player.GetInventory().HasInventoryReservation(mag, m_TargetInventoryLocation) )
318 //if ( !m_player.GetInventory().AddInventoryReservationEx( mag, m_TargetInventoryLocation, GameInventory.c_InventoryReservationTimeoutMS) )
319 {
320 m_player.GetInventory().ClearInventoryReservationEx(weapon, ilWeapon);
321 if (invLoc)
322 {
323 m_player.GetInventory().ClearInventoryReservationEx(invLoc.GetItem(), invLoc);
324 }
325 return false;
326 }
327 else
328 {
329 m_player.GetInventory().AddInventoryReservationEx(mag, m_TargetInventoryLocation, GameInventory.c_InventoryReservationTimeoutMS);
330 }
331 }
334
335 return true;
336 }
337
338//----------------------------------------------------------------------------
339// Weapon Actions
340//----------------------------------------------------------------------------
341 bool AttachMagazine( Magazine mag , ActionBase control_action = NULL )
342 {
343 return StartAction(AT_WPN_ATTACH_MAGAZINE, mag, NULL, control_action);
344 }
345
346 bool DetachMagazine( InventoryLocation invLoc, ActionBase control_action = NULL)
347 {
348 return StartAction(AT_WPN_DETACH_MAGAZINE, NULL, invLoc, control_action);
349 }
350
351 bool SwapMagazine( Magazine mag, ActionBase control_action = NULL )
352 {
355 {
356 return StartAction(AT_WPN_SWAP_MAGAZINE, mag, il, control_action);
357 }
358 return false;
359 }
360
361 bool SwapMagazineEx( Magazine mag, InventoryLocation invLoc, ActionBase control_action = NULL )
362 {
363 return StartAction(AT_WPN_SWAP_MAGAZINE, mag, invLoc, control_action);
364 }
365
366 bool LoadBullet( Magazine mag, ActionBase control_action = NULL )
367 {
368 return StartAction(AT_WPN_LOAD_BULLET, mag, NULL, control_action);
369 }
370
371 bool LoadMultiBullet( Magazine mag, ActionBase control_action = NULL )
372 {
373 return StartAction(AT_WPN_LOAD_MULTI_BULLETS_START, mag, NULL, control_action);
374 }
375
377 {
378 if(m_InProgress) m_WantContinue = false;
379 }
380
381 bool Unjam( ActionBase control_action = NULL )
382 {
383 return StartAction(AT_WPN_UNJAM, NULL, NULL, control_action);
384 }
385
386 bool EjectBullet( ActionBase control_action = NULL )
387 {
388 return StartAction(AT_WPN_EJECT_BULLET, NULL, NULL, control_action);
389 }
390
392 {
393 int mi = m_WeaponInHand.GetCurrentMuzzle();
394 if( !m_WeaponInHand.IsChamberFiredOut(mi) && !m_WeaponInHand.IsChamberEmpty(mi) )
395 {
396 int actual_time = GetGame().GetTime();
398 {
399 return false;
400 }
401 }
402 return true;
403 }
404
405 bool EjectBulletVerified( ActionBase control_action = NULL )
406 {
407 if ( m_WeaponInHand )
408 {
409 int mi = m_WeaponInHand.GetCurrentMuzzle();
410 if ( !m_WeaponInHand.IsChamberFiredOut(mi) && !m_WeaponInHand.IsChamberEmpty(mi) )
411 {
413 return StartAction(AT_WPN_EJECT_BULLET, NULL, NULL, control_action);
414 }
415 else
416 {
417 return StartAction(AT_WPN_EJECT_BULLET, NULL, NULL, control_action);
418 }
419 }
420 return false;
421 }
422
424 {
425 return StartAction(AT_WPN_SET_NEXT_MUZZLE_MODE, NULL, NULL, NULL);
426 }
427
429 {
430 int mi = wpn.GetCurrentMuzzle();
431 if ( wpn.IsChamberFiredOut(mi) || wpn.IsJammed() || wpn.IsChamberEmpty(mi) )
432 {
433 wpn.ProcessWeaponEvent(new WeaponEventTrigger(m_player));
434 return;
435 }
436
437 if (wpn.JamCheck(0))
438 {
439 wpn.ProcessWeaponEvent(new WeaponEventTriggerToJam(m_player));
440 }
441 else
442 {
443 wpn.ProcessWeaponEvent(new WeaponEventTrigger(m_player));
444 }
445 }
446
447#ifdef DIAG_DEVELOPER
448 int GetBurstOption()
449 {
450 return m_BurstOption;
451 }
452
453 void SetBurstOption(int value)
454 {
455 m_BurstOption = value;
456 }
457#endif
458//-------------------------------------------------------------------------------------
459// Synchronize - initialize from client side
460//-------------------------------------------------------------------------------------
461
462 //Client
463 private void Synchronize( )
464 {
465 if ( GetGame().IsClient() )
466 {
469
473
474
475 switch (m_PendingWeaponAction)
476 {
478 {
480 break;
481 }
483 {
486 break;
487 }
489 {
491 break;
492 }
494 {
496 break;
497 }
499 {
501 break;
502 }
503 case AT_WPN_UNJAM:
504 {
505 break;
506 }
508 {
509 break;
510 }
511 default:
512 break;
513 }
514 ctx.Send();
515 //if( !m_player.GetDayZPlayerInventory().HasLockedHands() )
516 // m_player.GetDayZPlayerInventory().LockHands();
517 }
518 }
519
520
521
522 void OnSyncJuncture(int pJunctureID, ParamsReadContext pCtx)
523 {
525 {
526 pCtx.Read(m_NewJamChance);
527 }
528 else
529 {
530 int AcknowledgmentID;
531 pCtx.Read(AcknowledgmentID);
532 if ( AcknowledgmentID == m_PendingWeaponActionAcknowledgmentID)
533 {
535 {
536 m_readyToStart = true;
537 }
539 {
540 if(m_PendingWeaponAction >= 0 )
541 {
542 if(!(GetGame().IsServer() && GetGame().IsMultiplayer()))
543 {
544 InventoryLocation ilWeapon = new InventoryLocation();
545 ItemBase weapon = m_player.GetItemInHands();
546 weapon.GetInventory().GetCurrentInventoryLocation(ilWeapon);
547 m_player.GetInventory().ClearInventoryReservationEx(m_player.GetItemInHands(),ilWeapon);
548
550 {
551 m_PendingTargetMagazine.GetInventory().ClearInventoryReservationEx(m_PendingTargetMagazine, m_TargetInventoryLocation );
552 }
553
555 {
556 m_player.GetInventory().ClearInventoryReservationEx( NULL, m_PendingInventoryLocation );
557 }
558 }
563 m_InProgress = false;
564 }
565 }
566 }
567 }
568 }
569
570
571 //Server
572 bool OnInputUserDataProcess(int userDataType, ParamsReadContext ctx)
573 {
574 Weapon_Base wpn;
575 int mi;
577 int slotID;
578 bool accepted = false;
579 if( userDataType == INPUT_UDT_WEAPON_ACTION)
580 {
581 if (!ctx.Read(m_PendingWeaponAction))
582 return false;
583
585 return false;
586
588 {
591 }
592 m_InProgress = true;
593 m_IsEventSended = false;
594 Magazine mag = NULL;
595
596 Weapon_Base.CastTo( wpn, m_player.GetItemInHands() );
597 if ( wpn )
598 mi = wpn.GetCurrentMuzzle();
599
600 switch (m_PendingWeaponAction)
601 {
603 {
604 if ( !ctx.Read(mag) )
605 break;
606
607 if ( !mag || !wpn )
608 break;
609
610 slotID = wpn.GetSlotFromMuzzleIndex(mi);
611 il = new InventoryLocation();
612 il.SetAttachment(wpn,mag,slotID);
613 if( GetGame().AddInventoryJunctureEx(m_player, mag, il, false, 10000) )
614 accepted = true;
615
617 break;
618 }
620 {
621 if ( !ctx.Read(mag) )
622 break;
623
624 il = new InventoryLocation();
625 if (!il.ReadFromContext(ctx))
626 break;
627
628 if ( !mag || !wpn )
629 break;
630
631 if ( !wpn.GetMagazine(mi) )
632 break;
633
634 if ( GetGame().AddActionJuncture(m_player,mag,10000) )
635 accepted = true;
638
639 break;
640 }
642 {
643 il = new InventoryLocation();
644 if ( !il.ReadFromContext(ctx) )
645 break;
646
647 if ( !il.IsValid() )
648 break;
649
650 if ( !wpn )
651 break;
652
653 Magazine det_mag = wpn.GetMagazine(mi);
654 mag = Magazine.Cast(il.GetItem());
655 if ( !det_mag || ( mag != det_mag) )
656 break;
657
658 if( GetGame().AddInventoryJunctureEx(m_player, il.GetItem(), il, true, 10000))
659 accepted = true;
662 break;
663 }
665 {
666 ctx.Read(mag);
667
668 if ( !mag )
669 break;
670
671 if( GetGame().AddActionJuncture(m_player,mag,10000) )
672 accepted = true;
674 break;
675 }
677 {
678 ctx.Read(mag);
679
680 if ( !mag )
681 break;
682
683 if( GetGame().AddActionJuncture(m_player,mag,10000) )
684 accepted = true;
686 break;
687 }
688 case AT_WPN_UNJAM:
689 {
690 accepted = true;
691 //Unjam();
692 break;
693 }
695 {
696 accepted = true;
697 break;
698 }
700 {
701 accepted = true;
702 break;
703 }
704 default:
705 Error("unknown actionID=" + m_PendingWeaponAction);
706 break;
707 }
709 }
710
711 return accepted;
712 }
713
714 bool StartAction(int action, Magazine mag, InventoryLocation il, ActionBase control_action = NULL)
715 {
716 //if it is controled by action inventory reservation and synchronization provide action itself
717 if(control_action)
718 {
719 m_ControlAction = ActionBase.Cast(control_action);
720 m_PendingWeaponAction = action;
721 m_InProgress = true;
722 m_IsEventSended = false;
726
727 return true;
728 }
729
730
731 if (GetGame().IsMultiplayer() && GetGame().IsServer())
732 return false;
733
735 return false;
736 if ( !InventoryReservation(mag, il) )
737 return false;
738
739 m_PendingWeaponAction = action;
740 m_InProgress = true;
741 m_IsEventSended = false;
742
743 if ( !GetGame().IsMultiplayer() )
744 m_readyToStart = true;
745 else
746 Synchronize();
747
748 return true;
749 }
750
752 {
753 m_WeaponInHand = Weapon_Base.Cast(m_player.GetItemInHands());
754 if(!m_WeaponInHand)
755 {
757 return;
758 }
759 switch (m_PendingWeaponAction)
760 {
762 {
763 m_player.GetDayZPlayerInventory().PostWeaponEvent( new WeaponEventAttachMagazine(m_player, m_PendingTargetMagazine) );
764 break;
765 }
767 {
768 m_player.GetDayZPlayerInventory().PostWeaponEvent( new WeaponEventSwapMagazine(m_player, m_PendingTargetMagazine, m_PendingInventoryLocation) );
769 break;
770 }
772 {
773 Magazine mag = Magazine.Cast(m_PendingInventoryLocation.GetItem());
774 m_player.GetDayZPlayerInventory().PostWeaponEvent( new WeaponEventDetachMagazine(m_player, mag, m_PendingInventoryLocation) );
775 break;
776 }
778 {
779 m_WantContinue = false;
780 m_player.GetDayZPlayerInventory().PostWeaponEvent( new WeaponEventLoad1Bullet(m_player, m_PendingTargetMagazine) );
781 break;
782 }
784 {
785 m_player.GetDayZPlayerInventory().PostWeaponEvent( new WeaponEventLoad1Bullet(m_player, m_PendingTargetMagazine) );
786 break;
787 }
789 {
790 m_player.GetDayZPlayerInventory().PostWeaponEvent( new WeaponEventContinuousLoadBulletEnd(m_player) );
791 break;
792 }
793 case AT_WPN_UNJAM:
794 {
795 m_player.GetDayZPlayerInventory().PostWeaponEvent( new WeaponEventUnjam(m_player, NULL) );
796 break;
797 }
799 {
800 m_player.GetDayZPlayerInventory().PostWeaponEvent( new WeaponEventMechanism(m_player, NULL) );
801 break;
802 }
804 {
805 m_player.GetDayZPlayerInventory().PostWeaponEvent( new WeaponEventSetNextMuzzleMode(m_player, NULL) );
806 break;
807 }
808 default:
809 m_InProgress = false;
810 Error("unknown actionID=" + m_PendingWeaponAction);
811 }
812 m_IsEventSended = true;
813 m_canEnd = false;
814 }
815
817 {
818 return m_InProgress;
819 }
820
821 void SetRunning( bool value)
822 {
823 m_InProgress = value;
824 }
825
826 void Refresh()
827 {
829 }
830
831 void Update( float deltaT )
832 {
833 if (m_WeaponInHand != m_player.GetItemInHands())
834 {
835 if( m_WeaponInHand )
836 {
837 m_SuitableMagazines.Clear();
839 }
840 m_WeaponInHand = Weapon_Base.Cast(m_player.GetItemInHands());
841 if ( m_WeaponInHand )
842 {
843 m_MagazineInHand = null;
844 //SET new magazine
846 m_WeaponInHand.SetSyncJammingChance(0);
847 }
849 }
850
851 if (m_WeaponInHand)
852 {
854 {
856
858 {
860 }
861 }
862
863 if (!GetGame().IsMultiplayer())
864 {
865 m_WeaponInHand.SetSyncJammingChance(m_WeaponInHand.GetChanceToJam());
866 }
867 else
868 {
869 if ( m_NewJamChance >= 0)
870 {
871 m_WeaponInHand.SetSyncJammingChance(m_NewJamChance);
872 m_NewJamChance = -1;
873 m_WaitToSyncJamChance = false;
874 }
875 if (GetGame().IsServer() && !m_WaitToSyncJamChance )
876 {
877 float actual_chance_to_jam;
878 actual_chance_to_jam = m_WeaponInHand.GetChanceToJam();
879 if ( Math.AbsFloat(m_WeaponInHand.GetSyncChanceToJam() - m_WeaponInHand.GetChanceToJam()) > 0.001 )
880 {
883 }
884 }
885 }
886
888 {
890 m_readyToStart = false;
891 return;
892 }
893
895 return;
896
897 if(m_canEnd)
898 {
899 if(m_WeaponInHand.IsIdle())
900 {
902 }
903 else if(m_justStart)
904 {
905 m_InIronSight = m_player.IsInIronsights();
906 m_InOptic = m_player.IsInOptics();
907
909 {
910 //'RequestResetADSSync' can be called here, if ADS reset is desired
911 m_player.ExitSights();
912 }
913
914 m_justStart = false;
915 }
916
917 }
918 else
919 {
920 m_canEnd = true;
921 m_justStart = true;
922 }
923 }
924 else
925 {
926 if ( m_MagazineInHand != m_player.GetItemInHands() )
927 {
928 m_MagazineInHand = MagazineStorage.Cast(m_player.GetItemInHands());
929 if ( m_MagazineInHand )
930 {
932 }
933 }
934
935
936 }
937 }
938
940 {
941 if ( !m_InProgress )
942 return;
943
944 if (!m_ControlAction)
945 {
946 if(GetGame().IsServer() && GetGame().IsMultiplayer())
947 {
949 {
951 }
952 }
953 else
954 {
956 il.SetHands(m_player,m_player.GetItemInHands());
957 m_player.GetInventory().ClearInventoryReservationEx(m_player.GetItemInHands(),il);
958
960 {
961 m_player.GetInventory().ClearInventoryReservationEx(m_PendingTargetMagazine, m_TargetInventoryLocation );
962 }
963
965 {
966 m_player.GetInventory().ClearInventoryReservationEx( m_PendingInventoryLocation.GetItem(), m_PendingInventoryLocation );
967 }
968 }
969 }
970
971 m_ControlAction = NULL;
977 //m_WeaponInHand = NULL;
978 m_InProgress = false;
979 m_readyToStart = false;
980 m_WantContinue = true;
981
982 }
983
985 {
987 {
988 if(delay == 0)
989 {
991 }
993 }
994 }
995
997 {
999 {
1000 WeaponStableState state = WeaponStableState.Cast( m_WeaponInHand.GetCurrentState() );
1001
1002 if (state)
1003 {
1004 HumanCommandWeapons hcw = m_player.GetCommandModifier_Weapons();
1005 if (hcw)
1006 {
1007 hcw.SetInitState(state.m_animState);
1008 }
1009 }
1010 }
1011 }
1012
1014 {
1015 return m_WantContinue;
1016 }
1017
1019 {
1020 for (int i = 0; i < m_SuitableMagazines.Count(); i++)
1021 {
1022 if(!m_SuitableMagazines.Get(i) || m_SuitableMagazines.Get(i).IsRuined() )
1023 {
1024 m_SuitableMagazines.Remove(i);
1025 i--;
1026 continue;
1027 }
1028 if (m_SuitableMagazines.Get(i).GetAmmoCount() > 0)
1029 return m_SuitableMagazines.Get(i);
1030 }
1031
1032 return null;
1033 }
1034
1035 Magazine GetNextPreparedMagazine( out int startIdx )
1036 {
1037 for (int i = startIdx; i < m_SuitableMagazines.Count(); i++)
1038 {
1039 if (m_SuitableMagazines.Get(i).GetAmmoCount() > 0)
1040 {
1041 startIdx = i;
1042 return m_SuitableMagazines.Get(i);
1043 }
1044 }
1045 return null;
1046 }
1047
1048 void OnMagazineInventoryEnter(Magazine mag)
1049 {
1050 if (mag)
1051 {
1052 Weapon_Base weapon = Weapon_Base.Cast(mag.GetHierarchyParent());
1053
1054 if (weapon)
1055 return;
1056 }
1057
1058 int i;
1059 MagazineStorage sMag = MagazineStorage.Cast(mag);
1060 if(sMag)
1061 {
1062 for(i = 0; i < m_MagazineStorageInInventory.Count(); i++ )
1063 {
1064 MagazineStorage s_mag_i = m_MagazineStorageInInventory[i];
1065 if(!s_mag_i)
1066 {
1067 m_MagazineStorageInInventory.RemoveOrdered(i);
1068 i--;
1069 continue;
1070 }
1071
1072 if(CompareMagazinesSuitability(s_mag_i,sMag)<0)
1073 break;
1074 }
1075 m_MagazineStorageInInventory.InsertAt(sMag,i);
1076
1077 SetSutableMagazines(); //TODO optimalize
1078 return;
1079 }
1080
1081 if(mag)
1082 {
1083
1084 for(i = 0; i < m_MagazinePilesInInventory.Count(); i++ )
1085 {
1086 Magazine mag_i = m_MagazinePilesInInventory[i];
1087 if(!mag_i)
1088 {
1089 m_MagazinePilesInInventory.RemoveOrdered(i);
1090 i--;
1091 continue;
1092 }
1093
1094
1095 if(CompareMagazinesSuitability(mag_i,mag)<0)
1096 {
1097 break;
1098 }
1099 }
1100 m_MagazinePilesInInventory.InsertAt(mag,i);
1101 SetSutableMagazines(); //TODO optimalize
1102 }
1103
1104 }
1105
1106 void OnMagazineInventoryExit(Magazine mag)
1107 {
1108 m_SuitableMagazines.RemoveItem(mag);
1109
1110 MagazineStorage sMag = MagazineStorage.Cast(mag);
1111 if(sMag)
1112 {
1113 m_MagazineStorageInInventory.RemoveItem(sMag);
1114 return;
1115 }
1116
1117 if(mag)
1118 {
1119 m_MagazinePilesInInventory.RemoveItem(mag);
1120 }
1121 }
1122
1123 void OnMagazineAttach(Magazine mag)
1124 {
1126 }
1127
1128 void OnMagazineDetach(Magazine mag)
1129 {
1131 }
1132
1133 int CompareMagazinesSuitability( Magazine mag1, Magazine mag2 )
1134 {
1135 return mag1.GetAmmoCount() - mag2.GetAmmoCount();
1136 }
1137
1139 {
1141 array<Magazine> magazines_piles = new array<Magazine>;
1142 int low_mag1, high_mag1;
1143 int low_mag2, high_mag2;
1144 int i, j;
1145
1146 for(i = 0; i < m_MagazineStorageInInventory.Count(); i++ )
1147 {
1148 MagazineStorage mag = m_MagazineStorageInInventory.Get(i);
1149 mag.GetNetworkID(low_mag1,high_mag1);
1150 for( j = 0; j < magazines.Count(); j++)
1151 {
1152 magazines.Get(j).GetNetworkID(low_mag2,high_mag2);
1153 if(low_mag1 > low_mag2)
1154 {
1155 break;
1156 }
1157 else if (low_mag1 == low_mag2)
1158 {
1159 if( high_mag1 > high_mag2 )
1160 {
1161 break;
1162 }
1163 }
1164 }
1165 magazines.InsertAt(mag,j);
1166 }
1167
1169 m_MagazineStorageInInventory.Copy(magazines);
1170
1171 for(i = 0; i < m_MagazinePilesInInventory.Count(); i++ )
1172 {
1173 Magazine pile = m_MagazinePilesInInventory.Get(i);
1174 pile.GetNetworkID(low_mag1,high_mag1);
1175 for( j = 0; j < magazines_piles.Count(); j++)
1176 {
1177 magazines_piles.Get(j).GetNetworkID(low_mag2,high_mag2);
1178 if(low_mag1 > low_mag2)
1179 {
1180 break;
1181 }
1182 else if (low_mag1 == low_mag2)
1183 {
1184 if( high_mag1 > high_mag2 )
1185 {
1186 break;
1187 }
1188 }
1189 }
1190 magazines_piles.InsertAt(pile,j);
1191 }
1192
1194 m_MagazinePilesInInventory.Copy(magazines_piles);
1195
1197 }
1198
1200 {
1201 m_SuitableMagazines.Clear();
1202 int i;
1203
1204 if (m_WeaponInHand)
1205 {
1206 int mi = m_WeaponInHand.GetCurrentMuzzle();
1207
1208 for (i = 0; i < m_MagazineStorageInInventory.Count(); i++ )
1209 {
1210 MagazineStorage s_mag = m_MagazineStorageInInventory[i];
1211
1212 if (!s_mag)
1213 {
1214 m_MagazineStorageInInventory.RemoveOrdered(i);
1215 i--;
1216 continue;
1217 }
1218
1219 if ( m_WeaponInHand.TestAttachMagazine(mi, s_mag, false, true))
1220 m_SuitableMagazines.Insert(s_mag);
1221 }
1222
1223 for (i = 0; i < m_MagazinePilesInInventory.Count(); i++ )
1224 {
1225 Magazine mag = m_MagazinePilesInInventory[i];
1226 if (!mag)
1227 {
1228 m_MagazinePilesInInventory.RemoveOrdered(i);
1229 i--;
1230 continue;
1231 }
1232
1233 if (m_WeaponInHand.CanChamberFromMag(mi, mag))
1234 m_SuitableMagazines.Insert(mag);
1235 }
1236//TODO m_MagazineStorageInInventory and m_MagazinePilesInInventory always sort
1237 }
1238 else if (m_MagazineInHand)
1239 {
1240 for (i = 0; i < m_MagazinePilesInInventory.Count(); i++ )
1241 {
1242 Magazine m_mag = m_MagazinePilesInInventory[i];
1243 if (!m_mag)
1244 {
1245 m_MagazinePilesInInventory.RemoveOrdered(i);
1246 i--;
1247 continue;
1248 }
1249 if (m_MagazineInHand.IsCompatiableAmmo( m_mag ))
1250 m_SuitableMagazines.Insert(m_mag);
1251 }
1252 }
1253 else
1254 {
1255 m_PreparedMagazine = null;
1256 }
1257
1258 }
1259
1261 {
1262 if( m_WeaponInHand )
1263 m_WeaponInHand.ResetBurstCount();
1264 }
1265
1267 {
1268 if( m_WeaponInHand )
1269 {
1270 int mi = m_WeaponInHand.GetCurrentMuzzle();
1271 return m_WeaponInHand.GetCurrentModeName(mi);
1272 }
1273 return "";
1274 }
1275
1276 bool PrepareInventoryLocationForMagazineSwap( notnull Weapon_Base wpn, notnull Magazine new_mag, out InventoryLocation new_il )
1277 {
1278 int muzzleIndex = wpn.GetCurrentMuzzle();
1279 Magazine old_mag = Magazine.Cast(wpn.GetMagazine(muzzleIndex));
1281
1282 if (old_mag)
1283 {
1284 bool result = GameInventory.CanSwapEntitiesEx(new_mag, old_mag);
1285 if ( result )
1286 {
1287 new_mag.GetInventory().GetCurrentInventoryLocation(new_il);
1288 new_il.SetItem(old_mag);
1289 }
1290 else
1291 {
1292 result = GameInventory.CanForceSwapEntitiesEx(new_mag, null, old_mag, new_il);
1293 float dir[4];
1294 if ( !result )
1295 {
1296 new_il.SetGroundEx( old_mag, m_player.GetPosition(), dir);
1297 }
1298 }
1299 }
1300 return true;
1301 }
1302}
const int INPUT_UDT_WEAPON_ACTION
Definition _constants.c:7
const int AT_WPN_DETACH_MAGAZINE
Definition _constants.c:12
const int AT_WPN_LOAD_MULTI_BULLETS_END
Definition _constants.c:17
const int AT_WPN_ATTACH_MAGAZINE
Definition _constants.c:10
const int AT_WPN_LOAD_BULLET
Definition _constants.c:13
const int AT_WPN_UNJAM
Definition _constants.c:14
const int AT_WPN_SWAP_MAGAZINE
Definition _constants.c:11
const int AT_WPN_LOAD_MULTI_BULLETS_START
Definition _constants.c:16
const int AT_WPN_EJECT_BULLET
Definition _constants.c:15
const int AT_WPN_SET_NEXT_MUZZLE_MODE
Definition _constants.c:18
void ActionBase()
Definition ActionBase.c:73
proto native bool ClearJuncture(Man player, notnull EntityAI item)
proto int GetTime()
returns mission time in milliseconds
Super root of all classes in Enforce script.
Definition EnScript.c:11
static const int SJ_WEAPON_ACTION_ACK_REJECT
static void SendWeaponActionAcknowledgment(DayZPlayer pPlayer, int AckID, bool accept)
static const int SJ_WEAPON_ACTION_ACK_ACCEPT
static void SendWeaponJamChance(DayZPlayer pPlayer, float jamChance)
static const int SJ_WEAPON_SET_JAMMING_CHANCE
script counterpart to engine's class Inventory
Definition Inventory.c:77
static bool CanForceSwapEntitiesEx(notnull EntityAI item1, InventoryLocation item1_dst, notnull EntityAI item2, out InventoryLocation item2_dst)
Definition Inventory.c:638
const int c_InventoryReservationTimeoutMS
reservations
Definition Inventory.c:683
static bool CanSwapEntitiesEx(notnull EntityAI item1, notnull EntityAI item2)
Definition Inventory.c:601
proto native void SetInitState(int pFrameIndex)
InventoryLocation.
proto native bool IsValid()
verify current set inventory location
proto native void SetHands(notnull EntityAI parent, EntityAI e)
sets current inventory location type to Hands
proto native EntityAI GetParent()
returns parent of current inventory location
bool ReadFromContext(ParamsReadContext ctx)
proto native void SetAttachment(notnull EntityAI parent, EntityAI e, int slotId)
sets current inventory location type to Attachment with slot id set to <slotId>
proto native EntityAI GetItem()
returns item of current inventory location
bool WriteToContext(ParamsWriteContext ctx)
provides access to slot configuration
Definition EnMath.c:7
proto static native bool CanStoreInputUserData()
proto native void Send()
Serialization general interface. Serializer API works with:
Definition Serializer.c:56
proto bool Write(void value_out)
proto bool Read(void value_in)
override float GetChanceToJam()
override bool CanChamberBullet(int muzzleIndex, Magazine mag)
Definition Magnum.c:165
override bool CanEjectBullet()
Definition Magnum.c:296
bool DetachMagazine(InventoryLocation invLoc, ActionBase control_action=NULL)
protected int m_PendingWeaponActionAcknowledgmentID
void Update(float deltaT)
protected int m_PendingWeaponAction
bool PrepareInventoryLocationForMagazineSwap(notnull Weapon_Base wpn, notnull Magazine new_mag, out InventoryLocation new_il)
protected ActionBase m_ControlAction
bool CanUnjam(Weapon_Base wpn, bool reservationCheck=true)
bool CanAttachMagazine(Weapon_Base wpn, Magazine mag, bool reservationCheck=true)
protected Magazine m_PendingTargetMagazine
protected ref array< Magazine > m_MagazinePilesInInventory
protected float m_NewJamChance
protected int m_LastAcknowledgmentID
protected ref InventoryLocation m_TargetInventoryLocation
bool Unjam(ActionBase control_action=NULL)
string GetCurrentModeName()
Magazine GetPreparedMagazine()
protected bool m_readyToStart
protected bool m_justStart
protected const int FORCE_EJECT_BULLET_TIMEOUT
bool StartAction(int action, Magazine mag, InventoryLocation il, ActionBase control_action=NULL)
bool CanEjectBulletVerified()
protected bool m_InProgress
protected ref array< MagazineStorage > m_MagazineStorageInInventory
void OnMagazineDetach(Magazine mag)
void SortMagazineAfterLoad()
void OnWeaponActionEnd()
protected bool m_WantContinue
protected bool m_WaitToSyncJamChance
bool CanDetachMagazine(Weapon_Base wpn, Magazine mag, bool reservationCheck=true)
protected MagazineStorage m_MagazineInHand
void RefreshAnimationState()
protected Magazine m_PreparedMagazine
protected Weapon_Base m_WeaponInHand
bool CanFire(Weapon_Base wpn)
protected ref array< Magazine > m_SuitableMagazines
protected bool m_canEnd
protected PlayerBase m_player
bool SetNextMuzzleMode()
bool AttachMagazine(Magazine mag, ActionBase control_action=NULL)
bool OnInputUserDataProcess(int userDataType, ParamsReadContext ctx)
void OnMagazineInventoryExit(Magazine mag)
protected ref InventoryLocation m_PendingInventoryLocation
bool EjectBullet(ActionBase control_action=NULL)
void OnMagazineAttach(Magazine mag)
void SetSutableMagazines()
void WeaponManager(PlayerBase player)
protected bool m_InIronSight
bool CanSwapMagazine(Weapon_Base wpn, Magazine mag, bool reservationCheck=true)
Magazine GetNextPreparedMagazine(out int startIdx)
void SetEjectBulletTryTimestamp()
protected bool m_InOptic
void OnMagazineInventoryEnter(Magazine mag)
void Fire(Weapon_Base wpn)
void LoadMultiBulletStop()
protected int m_ForceEjectBulletTimestamp
void DelayedRefreshAnimationState(int delay)
void OnSyncJuncture(int pJunctureID, ParamsReadContext pCtx)
const float MAX_DROP_MAGAZINE_DISTANCE_SQ
void SetRunning(bool value)
bool InventoryReservation(Magazine mag, InventoryLocation invLoc)
bool LoadBullet(Magazine mag, ActionBase control_action=NULL)
protected int m_AnimationRefreshCooldown
bool SwapMagazine(Magazine mag, ActionBase control_action=NULL)
protected bool m_IsEventSended
private void Synchronize()
bool CanEjectBullet(Weapon_Base wpn, bool reservationCheck=true)
void StartPendingAction()
int CompareMagazinesSuitability(Magazine mag1, Magazine mag2)
bool EjectBulletVerified(ActionBase control_action=NULL)
bool CanLoadBullet(Weapon_Base wpn, Magazine mag, bool reservationCheck=true)
bool LoadMultiBullet(Magazine mag, ActionBase control_action=NULL)
bool SwapMagazineEx(Magazine mag, InventoryLocation invLoc, ActionBase control_action=NULL)
represents weapon's stable state (i.e. the basic states that the weapon will spend the most time in)
Definition Crossbow.c:27
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
proto native CGame GetGame()
void Error(string err)
Messagebox with error message.
Definition EnDebug.c:90
static proto bool CastTo(out Class to, Class from)
Try to safely down-cast base class to child class.
static proto float AbsFloat(float f)
Returns absolute value.