Dayz Explorer 1.29.162510
Loading...
Searching...
No Matches
weaponmanager.c
Go to the documentation of this file.
2{
3 const float MAX_DROP_MAGAZINE_DISTANCE_SQ = 4;
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.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 !wpn.IsCoolDown();
88 }
89
90
91 bool CanAttachMagazine(Weapon_Base wpn, Magazine mag, bool reservationCheck = true )
92 {
93 if ( !wpn || !mag )
94 return false;
95
96 if ( m_player.GetEntityInHands() != wpn )
97 return false;
98
99 if ( wpn.IsDamageDestroyed())
100 return false;
101
102 //if ( mag.GetHierarchyRootPlayer() && mag.GetHierarchyRootPlayer() != m_player )
103 //return false;
104
105 if( m_player.IsItemsToDelete())
106 return false;
107
108 if ( reservationCheck && (m_player.GetInventory().HasInventoryReservation(wpn, null) || m_player.GetInventory().HasInventoryReservation(mag, null)))
109 return false;
110
111 InventoryLocation invLoc;
112 invLoc = new InventoryLocation();
113
114 mag.GetInventory().GetCurrentInventoryLocation(invLoc);
115 Weapon_Base wnp2;
116
117
118 //magazine is already in weapon
119 if ( Class.CastTo(wnp2, invLoc.GetParent()) )
120 return false;
121
122 int muzzleIndex = wpn.GetCurrentMuzzle();
123
124 if (wpn.CanAttachMagazine(muzzleIndex, mag))
125 return true;
126
127 return false;
128
129 }
130//---------------------------------------------------------------------------
131
132 bool CanSwapMagazine(Weapon_Base wpn, Magazine mag, bool reservationCheck = true)
133 {
134 if ( !wpn || !mag )
135 return false;
136
137 if ( m_player.GetEntityInHands() != wpn )
138 return false;
139
140 if ( mag.IsDamageDestroyed() || wpn.IsDamageDestroyed())
141 return false;
142
143 //if ( mag.GetHierarchyRootPlayer() && mag.GetHierarchyRootPlayer() != m_player )
144 //return false;
145
146 if( m_player.IsItemsToDelete())
147 return false;
148
149 if ( reservationCheck && (m_player.GetInventory().HasInventoryReservation(wpn, null) || m_player.GetInventory().HasInventoryReservation(mag, null)))
150 return false;
151
152
153 InventoryLocation invLoc;
154 invLoc = new InventoryLocation();
155
156 mag.GetInventory().GetCurrentInventoryLocation(invLoc);
157 Weapon_Base wnp2;
158
159 //second magazine is already in weapon
160 if( Class.CastTo(wnp2, invLoc.GetParent()) )
161 return false;
162
163 int muzzleIndex = wpn.GetCurrentMuzzle();
164
165 Magazine mag2;
166 if( !Class.CastTo(mag2, wpn.GetMagazine(muzzleIndex)) )
167 return false;
168
169 if( GameInventory.CanSwapEntitiesEx( mag, mag2 ) )
170 return true;
171
173
174 if( GameInventory.CanForceSwapEntitiesEx( mag, null, mag2, il ) )
175 return true;
176
177 return false;
178 }
179//----------------------------------------------------------------------------
180 bool CanDetachMagazine(Weapon_Base wpn, Magazine mag, bool reservationCheck = true)
181 {
182 if ( !wpn || !mag )
183 return false;
184
185 if ( m_player.GetEntityInHands() != wpn )
186 return false;
187
188 if ( mag.GetHierarchyParent() != wpn )
189 return false;
190
191 if( m_player.IsItemsToDelete())
192 return false;
193
194 if ( reservationCheck && (m_player.GetInventory().HasInventoryReservation(wpn, null) || m_player.GetInventory().HasInventoryReservation(mag, null)))
195 return false;
196
197 return true;
198 }
199//---------------------------------------------------------------------------
200 bool CanLoadBullet(Weapon_Base wpn, Magazine mag, bool reservationCheck = true)
201 {
202 if (!wpn || !mag)
203 return false;
204
205 if (m_player.GetEntityInHands() != wpn)
206 return false;
207
208 if (mag.IsDamageDestroyed() || wpn.IsDamageDestroyed())
209 return false;
210
211 if (wpn.IsJammed())
212 return false;
213
214 if (m_player.IsItemsToDelete())
215 return false;
216
217 if (reservationCheck && (m_player.GetInventory().HasInventoryReservation(wpn, null) || m_player.GetInventory().HasInventoryReservation(mag, null)))
218 return false;
219
220 for (int i = 0; i < wpn.GetMuzzleCount(); i++)
221 {
222 if (wpn.CanChamberBullet(i, mag))
223 {
224 return true;
225 }
226 }
227
228 return false;
229 }
230//---------------------------------------------------------------------------
231 bool CanLoadMultipleBullet(Weapon_Base wpn, Magazine mag, bool reservationCheck = true)
232 {
233 if (!wpn || !mag)
234 return false;
235
236 if (m_player.GetEntityInHands() != wpn)
237 return false;
238
239 if (mag.IsDamageDestroyed() || wpn.IsDamageDestroyed())
240 return false;
241
242 if (wpn.IsJammed())
243 return false;
244
245 if (m_player.IsItemsToDelete())
246 return false;
247
248 if (reservationCheck && (m_player.GetInventory().HasInventoryReservation(wpn, null) || m_player.GetInventory().HasInventoryReservation(mag, null)))
249 return false;
250
251 bool found = false;
252 bool fireout = false;
253 for (int i = 0; i < wpn.GetMuzzleCount(); i++)
254 {
255 if (fireout)
256 return true;
257
258 if (wpn.CanChamberBullet(i, mag) )
259 {
260 if (found)
261 {
262 return true;
263 }
264
265 if (wpn.HasInternalMagazine(i))
266 {
267 if ((wpn.GetInternalMagazineCartridgeCount(i)) < wpn.GetInternalMagazineMaxCartridgeCount(i))
268 {
269 return true;
270 }
271 }
272
273 if (wpn.IsChamberFiredOut(i))
274 {
275 if (i > 0)
276 return true;
277 fireout = true;
278 }
279 found = true;
280 }
281 }
282
283 return false;
284 }
285//---------------------------------------------------------------------------
286 bool CanUnjam(Weapon_Base wpn, bool reservationCheck = true)
287 {
288 if( !wpn )
289 return false;
290
291 if( m_player.GetEntityInHands() != wpn)
292 return false;
293
294 if( wpn.IsDamageDestroyed())
295 return false;
296
297 if( m_player.IsItemsToDelete())
298 return false;
299
300 if ( reservationCheck && m_player.GetInventory().HasInventoryReservation(wpn, null))
301 return false;
302
303
304 if( !wpn.IsJammed(/*wpn.GetCurrentMuzzle()*/) )
305 return false;
306
307 return true;
308 }
309
310 bool CanEjectBullet(Weapon_Base wpn, bool reservationCheck = true)
311 {
312 if( !wpn )
313 return false;
314
315 if( m_player.GetEntityInHands() != wpn)
316 return false;
317
318 if( m_player.IsItemsToDelete())
319 return false;
320
321 if( reservationCheck && m_player.GetInventory().HasInventoryReservation(wpn, null))
322 return false;
323
324 if( !wpn.CanEjectBullet() )
325 return false;
326
327 if( wpn.IsJammed(/*wpn.GetCurrentMuzzle()*/) )
328 return false;
329
330 return true;
331 }
332
337//----------------------------------------------------------------------------
338 bool InventoryReservation( Magazine mag, InventoryLocation invLoc)
339 {
340 Weapon_Base weapon;
341 InventoryLocation ilWeapon = new InventoryLocation();
342 GameInventory playerInventory = m_player.GetInventory();
343 if (Weapon_Base.CastTo(weapon, m_player.GetItemInHands()) )
344 {
345 weapon.GetInventory().GetCurrentInventoryLocation(ilWeapon);
346 if ( playerInventory.HasInventoryReservation(weapon, ilWeapon) )
347 {
348 return false;
349 }
350 else
351 {
353 }
354 }
355
356 if( invLoc )
357 {
358 if ( playerInventory.HasInventoryReservation(invLoc.GetItem(),invLoc) )
359 {
360 playerInventory.ClearInventoryReservationEx(weapon, ilWeapon);
361 return false;
362 }
363 else
364 {
365 playerInventory.AddInventoryReservationEx(invLoc.GetItem(),invLoc,GameInventory.c_InventoryReservationTimeoutMS);
366 }
367 }
368
369 if( mag )
370 {
372 m_TargetInventoryLocation.SetAttachment( m_WeaponInHand, mag, InventorySlots.MAGAZINE);
373
374 if ( playerInventory.HasInventoryReservation(mag, m_TargetInventoryLocation) )
375 //if ( !m_player.GetInventory().AddInventoryReservationEx( mag, m_TargetInventoryLocation, GameInventory.c_InventoryReservationTimeoutMS) )
376 {
377 playerInventory.ClearInventoryReservationEx(weapon, ilWeapon);
378 if (invLoc)
379 {
380 playerInventory.ClearInventoryReservationEx(invLoc.GetItem(), invLoc);
381 }
382 return false;
383 }
384 else
385 {
387 }
388 }
391
392 return true;
393 }
394
395//----------------------------------------------------------------------------
396// Weapon Actions
397//----------------------------------------------------------------------------
398 bool AttachMagazine( Magazine mag , ActionBase control_action = NULL )
399 {
400 return StartAction(AT_WPN_ATTACH_MAGAZINE, mag, NULL, control_action);
401 }
402
403 bool DetachMagazine( InventoryLocation invLoc, ActionBase control_action = NULL)
404 {
405 return StartAction(AT_WPN_DETACH_MAGAZINE, NULL, invLoc, control_action);
406 }
407
408 bool SwapMagazine( Magazine mag, ActionBase control_action = NULL )
409 {
411 if (PrepareInventoryLocationForMagazineSwap(m_WeaponInHand, mag, il) )
412 {
413 return StartAction(AT_WPN_SWAP_MAGAZINE, mag, il, control_action);
414 }
415 return false;
416 }
417
418 bool SwapMagazineEx( Magazine mag, InventoryLocation invLoc, ActionBase control_action = NULL )
419 {
420 return StartAction(AT_WPN_SWAP_MAGAZINE, mag, invLoc, control_action);
421 }
422
423 bool LoadBullet( Magazine mag, ActionBase control_action = NULL )
424 {
425 return StartAction(AT_WPN_LOAD_BULLET, mag, NULL, control_action);
426 }
427
428 bool LoadMultiBullet( Magazine mag, ActionBase control_action = NULL )
429 {
430 return StartAction(AT_WPN_LOAD_MULTI_BULLETS_START, mag, NULL, control_action);
431 }
432
434 {
435 if(m_InProgress) m_WantContinue = false;
436 }
437
438 bool Unjam( ActionBase control_action = NULL )
439 {
440 return StartAction(AT_WPN_UNJAM, NULL, NULL, control_action);
441 }
442
443 bool EjectBullet( ActionBase control_action = NULL )
444 {
445 return StartAction(AT_WPN_EJECT_BULLET, NULL, NULL, control_action);
446 }
447
449 {
450 int mi = m_WeaponInHand.GetCurrentMuzzle();
451 if( !m_WeaponInHand.IsChamberFiredOut(mi) && !m_WeaponInHand.IsChamberEmpty(mi) )
452 {
453 int actual_time = g_Game.GetTime();
455 {
456 return false;
457 }
458 }
459 return true;
460 }
461
462 bool EjectBulletVerified( ActionBase control_action = NULL )
463 {
464 if ( m_WeaponInHand )
465 {
466 int mi = m_WeaponInHand.GetCurrentMuzzle();
467 if ( !m_WeaponInHand.IsChamberFiredOut(mi) && !m_WeaponInHand.IsChamberEmpty(mi) )
468 {
470 return StartAction(AT_WPN_EJECT_BULLET, NULL, NULL, control_action);
471 }
472 else
473 {
474 return StartAction(AT_WPN_EJECT_BULLET, NULL, NULL, control_action);
475 }
476 }
477 return false;
478 }
479
481 {
482 return StartAction(AT_WPN_SET_NEXT_MUZZLE_MODE, NULL, NULL, NULL);
483 }
484
486 {
487 int mi = wpn.GetCurrentMuzzle();
488 if ( wpn.IsChamberFiredOut(mi) || wpn.IsJammed() || wpn.IsChamberEmpty(mi) )
489 {
490 wpn.ProcessWeaponEvent(new WeaponEventTrigger(m_player));
491 return;
492 }
493
494 if (wpn.JamCheck(0))
495 {
496 wpn.ProcessWeaponEvent(new WeaponEventTriggerToJam(m_player));
497 }
498 else
499 {
500 wpn.ProcessWeaponEvent(new WeaponEventTrigger(m_player));
501 }
502 }
503
504#ifdef DIAG_DEVELOPER
505 int GetBurstOption()
506 {
507 return m_BurstOption;
508 }
509
510 void SetBurstOption(int value)
511 {
512 m_BurstOption = value;
513 }
514#endif
515//-------------------------------------------------------------------------------------
516// Synchronize - initialize from client side
517//-------------------------------------------------------------------------------------
518
519 //Client
520 private void Synchronize( )
521 {
522 if ( g_Game.IsClient() )
523 {
525 ScriptInputUserData ctx = new ScriptInputUserData;
526
527 ctx.Write(INPUT_UDT_WEAPON_ACTION);
528 ctx.Write(m_PendingWeaponAction);
530
531
532 switch (m_PendingWeaponAction)
533 {
535 {
536 ctx.Write(m_PendingTargetMagazine);
537 break;
538 }
540 {
541 ctx.Write(m_PendingTargetMagazine);
542 m_PendingInventoryLocation.WriteToContext(ctx);
543 break;
544 }
546 {
547 m_PendingInventoryLocation.WriteToContext(ctx);
548 break;
549 }
551 {
552 ctx.Write(m_PendingTargetMagazine);
553 break;
554 }
556 {
557 ctx.Write(m_PendingTargetMagazine);
558 break;
559 }
560 case AT_WPN_UNJAM:
561 {
562 break;
563 }
565 {
566 break;
567 }
568 default:
569 break;
570 }
571 ctx.Send();
572 //if( !m_player.GetDayZPlayerInventory().HasLockedHands() )
573 // m_player.GetDayZPlayerInventory().LockHands();
574 }
575 }
576
577
578
579 void OnSyncJuncture(int pJunctureID, ParamsReadContext pCtx)
580 {
581 if (pJunctureID == DayZPlayerSyncJunctures.SJ_WEAPON_SET_JAMMING_CHANCE )
582 {
583 pCtx.Read(m_NewJamChance);
584 }
585 else
586 {
587 int AcknowledgmentID;
588 pCtx.Read(AcknowledgmentID);
589 if ( AcknowledgmentID == m_PendingWeaponActionAcknowledgmentID)
590 {
591 if (pJunctureID == DayZPlayerSyncJunctures.SJ_WEAPON_ACTION_ACK_ACCEPT)
592 {
593 m_readyToStart = true;
594 }
595 else if (pJunctureID == DayZPlayerSyncJunctures.SJ_WEAPON_ACTION_ACK_REJECT)
596 {
597 if(m_PendingWeaponAction >= 0 )
598 {
599 if(!(g_Game.IsServer() && g_Game.IsMultiplayer()))
600 {
601 InventoryLocation ilWeapon = new InventoryLocation();
602 ItemBase weapon = m_player.GetItemInHands();
603 GameInventory playerInventory = m_player.GetInventory();
604 weapon.GetInventory().GetCurrentInventoryLocation(ilWeapon);
605 playerInventory.ClearInventoryReservationEx(weapon, ilWeapon);
606
608 {
609 m_PendingTargetMagazine.GetInventory().ClearInventoryReservationEx(m_PendingTargetMagazine, m_TargetInventoryLocation );
610 }
611
613 {
615 }
616 }
621 m_InProgress = false;
622 }
623 }
624 }
625 }
626 }
627
628
629 //Server
630 bool OnInputUserDataProcess(int userDataType, ParamsReadContext ctx)
631 {
632 Weapon_Base wpn;
633 int mi;
634 InventoryLocation il;
635 int slotID;
636 bool accepted = false;
637 if( userDataType == INPUT_UDT_WEAPON_ACTION)
638 {
639 if (!ctx.Read(m_PendingWeaponAction))
640 return false;
641
643 return false;
644
646 {
647 g_Game.ClearJunctureEx(m_player, m_PendingTargetMagazine);
649 }
650 m_InProgress = true;
651 m_IsEventSended = false;
652 Magazine mag = NULL;
653
654 Weapon_Base.CastTo( wpn, m_player.GetItemInHands() );
655 if ( wpn )
656 mi = wpn.GetCurrentMuzzle();
657
658 switch (m_PendingWeaponAction)
659 {
661 {
662 if ( !ctx.Read(mag) )
663 break;
664
665 if ( !mag || !wpn )
666 break;
667
668 slotID = wpn.GetSlotFromMuzzleIndex(mi);
669 il = new InventoryLocation();
670 il.SetAttachment(wpn,mag,slotID);
671 if( g_Game.AddInventoryJunctureEx(m_player, mag, il, false, 10000) )
672 accepted = true;
673
675 break;
676 }
678 {
679 if ( !ctx.Read(mag) )
680 break;
681
682 il = new InventoryLocation();
683 if (!il.ReadFromContext(ctx))
684 break;
685
686 if ( !mag || !wpn )
687 break;
688
689 if ( !wpn.GetMagazine(mi) )
690 break;
691
692 if ( g_Game.AddActionJuncture(m_player,mag,10000) )
693 accepted = true;
696
697 break;
698 }
700 {
701 il = new InventoryLocation();
702 if ( !il.ReadFromContext(ctx) )
703 break;
704
705 if ( !il.IsValid() )
706 break;
707
708 if ( !wpn )
709 break;
710
711 Magazine det_mag = wpn.GetMagazine(mi);
712 mag = Magazine.Cast(il.GetItem());
713 if ( !det_mag || ( mag != det_mag) )
714 break;
715
716 if (g_Game.AddInventoryJunctureEx(m_player, il.GetItem(), il, true, 10000))
717 accepted = true;
720 break;
721 }
723 {
724 ctx.Read(mag);
725
726 if ( !mag )
727 break;
728
729 if( g_Game.AddActionJuncture(m_player,mag,10000) )
730 accepted = true;
732 break;
733 }
735 {
736 ctx.Read(mag);
737
738 if ( !mag )
739 break;
740
741 if( g_Game.AddActionJuncture(m_player,mag,10000) )
742 accepted = true;
744 break;
745 }
746 case AT_WPN_UNJAM:
747 {
748 accepted = true;
749 //Unjam();
750 break;
751 }
753 {
754 accepted = true;
755 break;
756 }
758 {
759 accepted = true;
760 break;
761 }
762 default:
763 Error("unknown actionID=" + m_PendingWeaponAction);
764 break;
765 }
766 DayZPlayerSyncJunctures.SendWeaponActionAcknowledgment(m_player, m_PendingWeaponActionAcknowledgmentID, accepted);
767 }
768
769 return accepted;
770 }
771
772 bool StartAction(int action, Magazine mag, InventoryLocation il, ActionBase control_action = NULL)
773 {
774 //if it is controled by action inventory reservation and synchronization provide action itself
775 if(control_action)
776 {
777 m_ControlAction = ActionBase.Cast(control_action);
778 m_PendingWeaponAction = action;
779 m_InProgress = true;
780 m_IsEventSended = false;
783 StartPendingAction();
784
785 return true;
786 }
787
788
789 if (g_Game.IsMultiplayer() && g_Game.IsServer())
790 return false;
791
792 if ( !ScriptInputUserData.CanStoreInputUserData() )
793 return false;
794 if ( !InventoryReservation(mag, il) )
795 return false;
796
797 m_PendingWeaponAction = action;
798 m_InProgress = true;
799 m_IsEventSended = false;
800
801 if ( !g_Game.IsMultiplayer() )
802 m_readyToStart = true;
803 else
804 Synchronize();
805
806 return true;
807 }
808
809 void StartPendingAction()
810 {
811 m_WeaponInHand = Weapon_Base.Cast(m_player.GetItemInHands());
812 if(!m_WeaponInHand)
813 {
814 OnWeaponActionEnd();
815 return;
816 }
817 switch (m_PendingWeaponAction)
818 {
820 {
821 m_player.GetDayZPlayerInventory().PostWeaponEvent( new WeaponEventAttachMagazine(m_player, m_PendingTargetMagazine) );
822 break;
823 }
825 {
826 m_player.GetDayZPlayerInventory().PostWeaponEvent( new WeaponEventSwapMagazine(m_player, m_PendingTargetMagazine, m_PendingInventoryLocation) );
827 break;
828 }
830 {
831 Magazine mag = Magazine.Cast(m_PendingInventoryLocation.GetItem());
832 m_player.GetDayZPlayerInventory().PostWeaponEvent( new WeaponEventDetachMagazine(m_player, mag, m_PendingInventoryLocation) );
833 break;
834 }
836 {
837 m_WantContinue = false;
838 m_player.GetDayZPlayerInventory().PostWeaponEvent( new WeaponEventLoad1Bullet(m_player, m_PendingTargetMagazine) );
839 break;
840 }
842 {
843 m_player.GetDayZPlayerInventory().PostWeaponEvent( new WeaponEventLoad1Bullet(m_player, m_PendingTargetMagazine) );
844 break;
845 }
847 {
848 m_player.GetDayZPlayerInventory().PostWeaponEvent( new WeaponEventContinuousLoadBulletEnd(m_player) );
849 break;
850 }
851 case AT_WPN_UNJAM:
852 {
853 m_player.GetDayZPlayerInventory().PostWeaponEvent( new WeaponEventUnjam(m_player, NULL) );
854 break;
855 }
857 {
858 m_player.GetDayZPlayerInventory().PostWeaponEvent( new WeaponEventMechanism(m_player, NULL) );
859 break;
860 }
862 {
863 m_player.GetDayZPlayerInventory().PostWeaponEvent( new WeaponEventSetNextMuzzleMode(m_player, NULL) );
864 break;
865 }
866 default:
867 m_InProgress = false;
868 Error("unknown actionID=" + m_PendingWeaponAction);
869 }
870 m_IsEventSended = true;
871 m_canEnd = false;
872 }
873
874 bool IsRunning()
875 {
876 return m_InProgress;
877 }
878
879 void SetRunning( bool value)
880 {
881 m_InProgress = value;
882 }
883
884 void Refresh()
885 {
886 OnWeaponActionEnd();
887 }
888
889 void Update( float deltaT )
890 {
891 if (m_WeaponInHand != m_player.GetItemInHands())
892 {
893 if( m_WeaponInHand )
894 {
895 m_SuitableMagazines.Clear();
896 OnWeaponActionEnd();
897 }
898 m_WeaponInHand = Weapon_Base.Cast(m_player.GetItemInHands());
899 if ( m_WeaponInHand )
900 {
901 m_MagazineInHand = null;
902 //SET new magazine
903 SetSutableMagazines();
904 m_WeaponInHand.SetSyncJammingChance(0);
905 }
907 }
908
909 if (m_WeaponInHand)
910 {
912 {
914
916 {
917 RefreshAnimationState();
918 }
919 }
920
921 if (!g_Game.IsMultiplayer())
922 {
923 m_WeaponInHand.SetSyncJammingChance(m_WeaponInHand.GetChanceToJam());
924 }
925 else
926 {
927 if ( m_NewJamChance >= 0)
928 {
929 m_WeaponInHand.SetSyncJammingChance(m_NewJamChance);
930 m_NewJamChance = -1;
931 m_WaitToSyncJamChance = false;
932 }
933 if (g_Game.IsServer() && !m_WaitToSyncJamChance )
934 {
935 float actual_chance_to_jam;
936 actual_chance_to_jam = m_WeaponInHand.GetChanceToJam();
937 if ( Math.AbsFloat(m_WeaponInHand.GetSyncChanceToJam() - m_WeaponInHand.GetChanceToJam()) > 0.001 )
938 {
939 DayZPlayerSyncJunctures.SendWeaponJamChance(m_player, m_WeaponInHand.GetChanceToJam());
941 }
942 }
943 }
944
946 {
947 StartPendingAction();
948 m_readyToStart = false;
949 return;
950 }
951
953 return;
954
955 if(m_canEnd)
956 {
957 if(m_WeaponInHand.IsIdle())
958 {
959 OnWeaponActionEnd();
960 }
961 else if(m_justStart)
962 {
963 m_InIronSight = m_player.IsInIronsights();
964 m_InOptic = m_player.IsInOptics();
965
967 {
968 //'RequestResetADSSync' can be called here, if ADS reset is desired
969 m_player.ExitSights();
970 }
971
972 m_justStart = false;
973 }
974
975 }
976 else
977 {
978 m_canEnd = true;
979 m_justStart = true;
980 }
981 }
982 else
983 {
984 if ( m_MagazineInHand != m_player.GetItemInHands() )
985 {
986 m_MagazineInHand = MagazineStorage.Cast(m_player.GetItemInHands());
987 if ( m_MagazineInHand )
988 {
989 SetSutableMagazines();
990 }
991 }
992
993
994 }
995 }
996
997 void OnWeaponActionEnd()
998 {
999 if ( !m_InProgress )
1000 return;
1001
1002 if (!m_ControlAction)
1003 {
1004 if (g_Game.IsServer() && g_Game.IsMultiplayer())
1005 {
1007 {
1008 g_Game.ClearJunctureEx(m_player,m_PendingTargetMagazine);
1009 }
1010 }
1011 else
1012 {
1013 InventoryLocation il = new InventoryLocation();
1014 ItemBase itemInHands = m_player.GetItemInHands();
1015 GameInventory playerInventory = m_player.GetInventory();
1016 il.SetHands(m_player, itemInHands);
1017 playerInventory.ClearInventoryReservationEx(itemInHands, il);
1018
1020 {
1022 }
1023
1025 {
1027 }
1028 }
1029 }
1030
1031 m_ControlAction = NULL;
1037 //m_WeaponInHand = NULL;
1038 m_InProgress = false;
1039 m_readyToStart = false;
1040 m_WantContinue = true;
1041
1042 }
1043
1044 void DelayedRefreshAnimationState(int delay)
1045 {
1046 if(m_WeaponInHand)
1047 {
1048 if(delay == 0)
1049 {
1050 RefreshAnimationState();
1051 }
1053 }
1054 }
1055
1056 void RefreshAnimationState()
1057 {
1058 if(m_WeaponInHand)
1059 {
1060 WeaponStableState state = WeaponStableState.Cast( m_WeaponInHand.GetCurrentState() );
1061
1062 if (state)
1063 {
1064 HumanCommandWeapons hcw = m_player.GetCommandModifier_Weapons();
1065 if (hcw)
1066 {
1067 hcw.SetInitState(state.m_animState);
1068 }
1069 }
1070 }
1071 }
1072
1073 bool WantContinue()
1074 {
1075 return m_WantContinue;
1076 }
1077
1078 Magazine GetPreparedMagazine()
1079 {
1080 Magazine mag;
1081 for (int i = 0; i < m_SuitableMagazines.Count(); i++)
1082 {
1083 mag = m_SuitableMagazines[i];
1084 if (!mag || mag.IsRuined() || (mag.GetHierarchyParent() && mag.GetHierarchyParent().IsWeapon()) )
1085 {
1086 m_SuitableMagazines.Remove(i);
1087 i--;
1088 continue;
1089 }
1090
1091 if(!mag.GetHierarchyParent() || mag.GetHierarchyParent().GetInventory().AreChildrenAccessible())
1092 {
1093 if (mag.GetAmmoCount() > 0)
1094 return mag;
1095 }
1096 }
1097
1098 return null;
1099 }
1100
1101 Magazine GetNextPreparedMagazine( out int startIdx )
1102 {
1103 int count = m_SuitableMagazines.Count();
1104 Magazine mag;
1105 for (int i = startIdx; i < count; ++i)
1106 {
1107 mag = m_SuitableMagazines[i];
1108 if (mag && mag.GetAmmoCount() > 0 && (!mag.GetHierarchyParent() || mag.GetHierarchyParent().GetInventory().AreChildrenAccessible()))
1109 {
1110 startIdx = i;
1111 return m_SuitableMagazines.Get(i);
1112 }
1113 }
1114 return null;
1115 }
1116
1117 void OnMagazineInventoryEnter(Magazine mag)
1118 {
1119 if (mag)
1120 {
1121 Weapon_Base weapon = Weapon_Base.Cast(mag.GetHierarchyParent());
1122
1123 if (weapon)
1124 return;
1125 }
1126
1127 int i;
1128 MagazineStorage sMag = MagazineStorage.Cast(mag);
1129 if(sMag)
1130 {
1131 for(i = 0; i < m_MagazineStorageInInventory.Count(); i++ )
1132 {
1133 MagazineStorage s_mag_i = m_MagazineStorageInInventory[i];
1134 if(!s_mag_i)
1135 {
1136 m_MagazineStorageInInventory.RemoveOrdered(i);
1137 i--;
1138 continue;
1139 }
1140
1141 if(CompareMagazinesSuitability(s_mag_i,sMag)<0)
1142 break;
1143 }
1144 m_MagazineStorageInInventory.InsertAt(sMag,i);
1145
1146 SetSutableMagazines(); //TODO optimalize
1147 return;
1148 }
1149
1150 if(mag)
1151 {
1152
1153 for(i = 0; i < m_MagazinePilesInInventory.Count(); i++ )
1154 {
1155 Magazine mag_i = m_MagazinePilesInInventory[i];
1156 if(!mag_i)
1157 {
1158 m_MagazinePilesInInventory.RemoveOrdered(i);
1159 i--;
1160 continue;
1161 }
1162
1163
1164 if(CompareMagazinesSuitability(mag_i,mag)<0)
1165 {
1166 break;
1167 }
1168 }
1169 m_MagazinePilesInInventory.InsertAt(mag,i);
1170 SetSutableMagazines(); //TODO optimalize
1171 }
1172
1173 }
1174
1175 void OnMagazineInventoryExit(Magazine mag)
1176 {
1177 m_SuitableMagazines.RemoveItem(mag);
1178
1179 MagazineStorage sMag = MagazineStorage.Cast(mag);
1180 if(sMag)
1181 {
1182 m_MagazineStorageInInventory.RemoveItem(sMag);
1183 return;
1184 }
1185
1186 if(mag)
1187 {
1188 m_MagazinePilesInInventory.RemoveItem(mag);
1189 }
1190 }
1191
1192 void OnMagazineAttach(Magazine mag)
1193 {
1194 OnMagazineInventoryExit(mag);
1195 }
1196
1197 void OnMagazineDetach(Magazine mag)
1198 {
1199 OnMagazineInventoryEnter(mag);
1200 }
1201
1202 int CompareMagazinesSuitability( Magazine mag1, Magazine mag2 )
1203 {
1204 return mag1.GetAmmoCount() - mag2.GetAmmoCount();
1205 }
1206
1207 void SortMagazineAfterLoad()
1208 {
1209 array<MagazineStorage> magazines = new array<MagazineStorage>;
1210 array<Magazine> magazines_piles = new array<Magazine>;
1211 int low_mag1, high_mag1;
1212 int low_mag2, high_mag2;
1213 int i, j;
1214
1215 for(i = 0; i < m_MagazineStorageInInventory.Count(); i++ )
1216 {
1217 MagazineStorage mag = m_MagazineStorageInInventory.Get(i);
1218 mag.GetNetworkID(low_mag1,high_mag1);
1219 for( j = 0; j < magazines.Count(); j++)
1220 {
1221 magazines.Get(j).GetNetworkID(low_mag2,high_mag2);
1222 if(low_mag1 > low_mag2)
1223 {
1224 break;
1225 }
1226 else if (low_mag1 == low_mag2)
1227 {
1228 if( high_mag1 > high_mag2 )
1229 {
1230 break;
1231 }
1232 }
1233 }
1234 magazines.InsertAt(mag,j);
1235 }
1236
1238 m_MagazineStorageInInventory.Copy(magazines);
1239
1240 for(i = 0; i < m_MagazinePilesInInventory.Count(); i++ )
1241 {
1242 Magazine pile = m_MagazinePilesInInventory.Get(i);
1243 pile.GetNetworkID(low_mag1,high_mag1);
1244 for( j = 0; j < magazines_piles.Count(); j++)
1245 {
1246 magazines_piles.Get(j).GetNetworkID(low_mag2,high_mag2);
1247 if(low_mag1 > low_mag2)
1248 {
1249 break;
1250 }
1251 else if (low_mag1 == low_mag2)
1252 {
1253 if( high_mag1 > high_mag2 )
1254 {
1255 break;
1256 }
1257 }
1258 }
1259 magazines_piles.InsertAt(pile,j);
1260 }
1261
1263 m_MagazinePilesInInventory.Copy(magazines_piles);
1264
1265 SetSutableMagazines();
1266 }
1267
1268 void SetSutableMagazines()
1269 {
1270 m_SuitableMagazines.Clear();
1271 int i;
1272
1273 if (m_WeaponInHand)
1274 {
1275 int mi = m_WeaponInHand.GetCurrentMuzzle();
1276
1277 for (i = 0; i < m_MagazineStorageInInventory.Count(); i++ )
1278 {
1279 MagazineStorage s_mag = m_MagazineStorageInInventory[i];
1280
1281 if (!s_mag)
1282 {
1283 m_MagazineStorageInInventory.RemoveOrdered(i);
1284 i--;
1285 continue;
1286 }
1287
1288 if ( m_WeaponInHand.TestAttachMagazine(mi, s_mag, false, true))
1289 m_SuitableMagazines.Insert(s_mag);
1290 }
1291
1292 for (i = 0; i < m_MagazinePilesInInventory.Count(); i++ )
1293 {
1294 Magazine mag = m_MagazinePilesInInventory[i];
1295 if (!mag)
1296 {
1297 m_MagazinePilesInInventory.RemoveOrdered(i);
1298 i--;
1299 continue;
1300 }
1301
1302 if (m_WeaponInHand.CanChamberFromMag(mi, mag))
1303 m_SuitableMagazines.Insert(mag);
1304 }
1305//TODO m_MagazineStorageInInventory and m_MagazinePilesInInventory always sort
1306 }
1307 else if (m_MagazineInHand)
1308 {
1309 for (i = 0; i < m_MagazinePilesInInventory.Count(); i++ )
1310 {
1311 Magazine m_mag = m_MagazinePilesInInventory[i];
1312 if (!m_mag)
1313 {
1314 m_MagazinePilesInInventory.RemoveOrdered(i);
1315 i--;
1316 continue;
1317 }
1318 if (m_MagazineInHand.IsCompatiableAmmo( m_mag ))
1319 m_SuitableMagazines.Insert(m_mag);
1320 }
1321 }
1322 else
1323 {
1324 m_PreparedMagazine = null;
1325 }
1326
1327 }
1328
1329 void OnLiftWeapon()
1330 {
1331 if( m_WeaponInHand )
1332 m_WeaponInHand.ResetBurstCount();
1333 }
1334
1335 string GetCurrentModeName()
1336 {
1337 if( m_WeaponInHand )
1338 {
1339 int mi = m_WeaponInHand.GetCurrentMuzzle();
1340 return m_WeaponInHand.GetCurrentModeName(mi);
1341 }
1342 return "";
1343 }
1344
1345 bool PrepareInventoryLocationForMagazineSwap( notnull Weapon_Base wpn, notnull Magazine new_mag, out InventoryLocation new_il )
1346 {
1347 int muzzleIndex = wpn.GetCurrentMuzzle();
1348 Magazine old_mag = Magazine.Cast(wpn.GetMagazine(muzzleIndex));
1349 InventoryLocation temp = new InventoryLocation();
1350
1351 if (old_mag)
1352 {
1353 bool result = GameInventory.CanSwapEntitiesEx(new_mag, old_mag);
1354 if ( result )
1355 {
1356 new_mag.GetInventory().GetCurrentInventoryLocation(new_il);
1357 new_il.SetItem(old_mag);
1358 }
1359 else
1360 {
1361 result = GameInventory.CanForceSwapEntitiesEx(new_mag, null, old_mag, new_il);
1362 float dir[4];
1363 if ( !result )
1364 {
1365 new_il.SetGroundEx( old_mag, m_player.GetPosition(), dir);
1366 }
1367 }
1368 }
1369 return true;
1370 }
1371}
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
Super root of all classes in Enforce script.
Definition enscript.c:11
script counterpart to engine's class Inventory
Definition inventory.c:81
bool ClearInventoryReservationEx(EntityAI item, InventoryLocation dst)
Definition inventory.c:764
static bool CanSwapEntitiesEx(notnull EntityAI item1, notnull EntityAI item2)
Definition inventory.c:630
const int c_InventoryReservationTimeoutMS
reservations
Definition inventory.c:714
static proto native bool HasInventoryReservation(EntityAI item, InventoryLocation dst)
Internally: HasInventoryReservationEx(item, dst, FindInventoryReservationMode.LEGACY,...
static bool CanForceSwapEntitiesEx(notnull EntityAI item1, InventoryLocation item1_dst, notnull EntityAI item2, out InventoryLocation item2_dst)
Definition inventory.c:666
bool AddInventoryReservationEx(EntityAI item, InventoryLocation dst, int timeout_ms)
Definition inventory.c:718
InventoryLocation.
provides access to slot configuration
bool EjectBulletVerified(ActionBase control_action=NULL)
PlayerBase m_player
bool CanUnjam(Weapon_Base wpn, bool reservationCheck=true)
bool CanEjectBulletVerified()
bool CanLoadBullet(Weapon_Base wpn, Magazine mag, bool reservationCheck=true)
bool CanAttachMagazine(Weapon_Base wpn, Magazine mag, bool reservationCheck=true)
ActionBase m_ControlAction
int m_PendingWeaponActionAcknowledgmentID
ref array< Magazine > m_MagazinePilesInInventory
bool AttachMagazine(Magazine mag, ActionBase control_action=NULL)
int m_ForceEjectBulletTimestamp
bool LoadBullet(Magazine mag, ActionBase control_action=NULL)
bool CanEjectBullet(Weapon_Base wpn, bool reservationCheck=true)
bool LoadMultiBullet(Magazine mag, ActionBase control_action=NULL)
Magazine m_PendingTargetMagazine
bool DetachMagazine(InventoryLocation invLoc, ActionBase control_action=NULL)
void LoadMultiBulletStop()
bool CanLoadMultipleBullet(Weapon_Base wpn, Magazine mag, bool reservationCheck=true)
bool SetNextMuzzleMode()
int m_LastAcknowledgmentID
bool m_WaitToSyncJamChance
ref array< Magazine > m_SuitableMagazines
bool CanSwapMagazine(Weapon_Base wpn, Magazine mag, bool reservationCheck=true)
Weapon_Base m_WeaponInHand
bool SwapMagazine(Magazine mag, ActionBase control_action=NULL)
const int FORCE_EJECT_BULLET_TIMEOUT
ref array< MagazineStorage > m_MagazineStorageInInventory
bool CanFire(Weapon_Base wpn)
bool CanDetachMagazine(Weapon_Base wpn, Magazine mag, bool reservationCheck=true)
void SetEjectBulletTryTimestamp()
Magazine m_PreparedMagazine
bool Unjam(ActionBase control_action=NULL)
void WeaponManager(PlayerBase player)
ref InventoryLocation m_PendingInventoryLocation
bool SwapMagazineEx(Magazine mag, InventoryLocation invLoc, ActionBase control_action=NULL)
void Fire(Weapon_Base wpn)
ref InventoryLocation m_TargetInventoryLocation
bool EjectBullet(ActionBase control_action=NULL)
int m_PendingWeaponAction
MagazineStorage m_MagazineInHand
int m_AnimationRefreshCooldown
bool InventoryReservation(Magazine mag, InventoryLocation invLoc)
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
void Synchronize()
DayZGame g_Game
Definition dayzgame.c:3942
Serializer ParamsReadContext
Definition gameplay.c:15
class GP5GasMask extends MaskBase ItemBase
void Error(string err)
Messagebox with error message.
Definition endebug.c:90
bool IsRunning()
Definition tools.c:264
void Update()
Definition radialmenu.c:518
void Refresh()
void WeaponStableState(Weapon_Base w=NULL, WeaponStateBase parent=NULL, int anim_state=-1)