3 const float MAX_DROP_MAGAZINE_DISTANCE_SQ = 4;
7 protected int m_LastAcknowledgmentID;
9 protected int m_PendingWeaponActionAcknowledgmentID;
10 protected Magazine m_PendingTargetMagazine;
12 protected int m_PendingWeaponAction;
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;
26 protected int m_ForceEjectBulletTimestamp;
28 protected const int FORCE_EJECT_BULLET_TIMEOUT = 2000;
30 protected int m_BurstOption;
36 protected Magazine m_PreparedMagazine;
39 protected float m_NewJamChance;
40 protected bool m_WaitToSyncJamChance;
43 protected int m_AnimationRefreshCooldown;
47 m_ForceEjectBulletTimestamp = -1;
49 m_PendingWeaponActionAcknowledgmentID = -1;
50 m_PendingTargetMagazine = NULL;
51 m_PendingInventoryLocation = NULL;
52 m_WeaponInHand = NULL;
53 m_MagazineInHand = NULL;
54 m_ControlAction = NULL;
55 m_PendingWeaponAction = -1;
56 m_LastAcknowledgmentID = 1;
58 m_WantContinue =
true;
59 m_IsEventSended =
false;
61 m_readyToStart =
false;
62 m_AnimationRefreshCooldown = 0;
65 m_WaitToSyncJamChance =
false;
70 m_PreparedMagazine =
null;
81 if(
m_player.GetHumanInventory().GetEntityInHands() != wpn )
92 bool CanAttachMagazine(
Weapon_Base wpn, Magazine mag,
bool reservationCheck =
true )
97 if (
m_player.GetHumanInventory().GetEntityInHands() != wpn )
100 if ( wpn.IsDamageDestroyed())
109 if ( reservationCheck && (
m_player.GetInventory().HasInventoryReservation(wpn,
null) ||
m_player.GetInventory().HasInventoryReservation(mag,
null)))
115 mag.GetInventory().GetCurrentInventoryLocation(invLoc);
120 if (
Class.CastTo(wnp2, invLoc.GetParent()) )
123 int muzzleIndex = wpn.GetCurrentMuzzle();
125 if (wpn.CanAttachMagazine(muzzleIndex, mag))
133 bool CanSwapMagazine(
Weapon_Base wpn, Magazine mag,
bool reservationCheck =
true)
138 if (
m_player.GetHumanInventory().GetEntityInHands() != wpn )
141 if ( mag.IsDamageDestroyed() || wpn.IsDamageDestroyed())
150 if ( reservationCheck && (
m_player.GetInventory().HasInventoryReservation(wpn,
null) ||
m_player.GetInventory().HasInventoryReservation(mag,
null)))
157 mag.GetInventory().GetCurrentInventoryLocation(invLoc);
161 if(
Class.CastTo(wnp2, invLoc.GetParent()) )
164 int muzzleIndex = wpn.GetCurrentMuzzle();
167 if( !
Class.CastTo(mag2, wpn.GetMagazine(muzzleIndex)) )
175 if(
GameInventory.CanForceSwapEntitiesEx( mag,
null, mag2, il ) )
181 bool CanDetachMagazine(
Weapon_Base wpn, Magazine mag,
bool reservationCheck =
true)
186 if (
m_player.GetHumanInventory().GetEntityInHands() != wpn )
189 if ( mag.GetHierarchyParent() != wpn )
195 if ( reservationCheck && (
m_player.GetInventory().HasInventoryReservation(wpn,
null) ||
m_player.GetInventory().HasInventoryReservation(mag,
null)))
201 bool CanLoadBullet(
Weapon_Base wpn, Magazine mag,
bool reservationCheck =
true)
206 if (
m_player.GetHumanInventory().GetEntityInHands() != wpn)
209 if (mag.IsDamageDestroyed() || wpn.IsDamageDestroyed())
218 if (reservationCheck && (
m_player.GetInventory().HasInventoryReservation(wpn,
null) ||
m_player.GetInventory().HasInventoryReservation(mag,
null)))
221 for (
int i = 0; i < wpn.GetMuzzleCount(); i++)
223 if (wpn.CanChamberBullet(i, mag))
230 bool CanUnjam(
Weapon_Base wpn,
bool reservationCheck =
true)
235 if(
m_player.GetHumanInventory().GetEntityInHands() != wpn)
238 if( wpn.IsDamageDestroyed())
244 if ( reservationCheck &&
m_player.GetInventory().HasInventoryReservation(wpn,
null))
248 if( !wpn.IsJammed() )
254 bool CanEjectBullet(
Weapon_Base wpn,
bool reservationCheck =
true)
259 if(
m_player.GetHumanInventory().GetEntityInHands() != wpn)
265 if( reservationCheck &&
m_player.GetInventory().HasInventoryReservation(wpn,
null))
268 if( !wpn.CanEjectBullet() )
277 void SetEjectBulletTryTimestamp()
279 m_ForceEjectBulletTimestamp =
GetGame().GetTime();
288 weapon.GetInventory().GetCurrentInventoryLocation(ilWeapon);
289 if (
m_player.GetInventory().HasInventoryReservation(weapon, ilWeapon) )
295 m_player.GetInventory().AddInventoryReservationEx(weapon,ilWeapon,
GameInventory.c_InventoryReservationTimeoutMS);
301 if (
m_player.GetInventory().HasInventoryReservation(invLoc.GetItem(),invLoc) )
303 m_player.GetInventory().ClearInventoryReservationEx(weapon, ilWeapon);
308 m_player.GetInventory().AddInventoryReservationEx(invLoc.GetItem(),invLoc,
GameInventory.c_InventoryReservationTimeoutMS);
315 m_TargetInventoryLocation.SetAttachment( m_WeaponInHand, mag,
InventorySlots.MAGAZINE);
317 if (
m_player.GetInventory().HasInventoryReservation(mag, m_TargetInventoryLocation) )
320 m_player.GetInventory().ClearInventoryReservationEx(weapon, ilWeapon);
323 m_player.GetInventory().ClearInventoryReservationEx(invLoc.GetItem(), invLoc);
329 m_player.GetInventory().AddInventoryReservationEx(mag, m_TargetInventoryLocation,
GameInventory.c_InventoryReservationTimeoutMS);
332 m_PendingTargetMagazine = mag;
333 m_PendingInventoryLocation = invLoc;
341 bool AttachMagazine( Magazine mag ,
ActionBase control_action = NULL )
351 bool SwapMagazine( Magazine mag,
ActionBase control_action = NULL )
354 if (PrepareInventoryLocationForMagazineSwap(m_WeaponInHand, mag, il) )
366 bool LoadBullet( Magazine mag,
ActionBase control_action = NULL )
371 bool LoadMultiBullet( Magazine mag,
ActionBase control_action = NULL )
376 void LoadMultiBulletStop( )
378 if(m_InProgress) m_WantContinue =
false;
381 bool Unjam(
ActionBase control_action = NULL )
383 return StartAction(
AT_WPN_UNJAM, NULL, NULL, control_action);
386 bool EjectBullet(
ActionBase control_action = NULL )
391 bool CanEjectBulletVerified()
393 int mi = m_WeaponInHand.GetCurrentMuzzle();
394 if( !m_WeaponInHand.IsChamberFiredOut(mi) && !m_WeaponInHand.IsChamberEmpty(mi) )
396 int actual_time =
GetGame().GetTime();
397 if ( actual_time - m_ForceEjectBulletTimestamp > FORCE_EJECT_BULLET_TIMEOUT )
405 bool EjectBulletVerified(
ActionBase control_action = NULL )
407 if ( m_WeaponInHand )
409 int mi = m_WeaponInHand.GetCurrentMuzzle();
410 if ( !m_WeaponInHand.IsChamberFiredOut(mi) && !m_WeaponInHand.IsChamberEmpty(mi) )
412 m_ForceEjectBulletTimestamp =
GetGame().GetTime();
423 bool SetNextMuzzleMode ()
430 int mi = wpn.GetCurrentMuzzle();
431 if ( wpn.IsChamberFiredOut(mi) || wpn.IsJammed() || wpn.IsChamberEmpty(mi) )
433 wpn.ProcessWeaponEvent(
new WeaponEventTrigger(
m_player));
439 wpn.ProcessWeaponEvent(
new WeaponEventTriggerToJam(
m_player));
443 wpn.ProcessWeaponEvent(
new WeaponEventTrigger(
m_player));
447 #ifdef DIAG_DEVELOPER
450 return m_BurstOption;
453 void SetBurstOption(
int value)
455 m_BurstOption = value;
463 private void Synchronize( )
467 m_PendingWeaponActionAcknowledgmentID = ++m_LastAcknowledgmentID;
471 ctx.Write(m_PendingWeaponAction);
472 ctx.Write(m_PendingWeaponActionAcknowledgmentID);
475 switch (m_PendingWeaponAction)
479 ctx.Write(m_PendingTargetMagazine);
484 ctx.Write(m_PendingTargetMagazine);
485 m_PendingInventoryLocation.WriteToContext(ctx);
490 m_PendingInventoryLocation.WriteToContext(ctx);
495 ctx.Write(m_PendingTargetMagazine);
500 ctx.Write(m_PendingTargetMagazine);
526 pCtx.Read(m_NewJamChance);
530 int AcknowledgmentID;
531 pCtx.Read(AcknowledgmentID);
532 if ( AcknowledgmentID == m_PendingWeaponActionAcknowledgmentID)
536 m_readyToStart =
true;
540 if(m_PendingWeaponAction >= 0 )
546 weapon.GetInventory().GetCurrentInventoryLocation(ilWeapon);
547 m_player.GetInventory().ClearInventoryReservationEx(
m_player.GetItemInHands(),ilWeapon);
549 if( m_PendingTargetMagazine )
551 m_PendingTargetMagazine.GetInventory().ClearInventoryReservationEx(m_PendingTargetMagazine, m_TargetInventoryLocation );
554 if( m_PendingInventoryLocation )
556 m_player.GetInventory().ClearInventoryReservationEx( NULL, m_PendingInventoryLocation );
559 m_PendingWeaponActionAcknowledgmentID = -1;
560 m_PendingTargetMagazine = NULL;
561 m_PendingWeaponAction = -1;
562 m_PendingInventoryLocation = NULL;
563 m_InProgress =
false;
578 bool accepted =
false;
581 if (!ctx.Read(m_PendingWeaponAction))
584 if (!ctx.Read(m_PendingWeaponActionAcknowledgmentID))
587 if(m_PendingTargetMagazine)
590 m_PendingTargetMagazine = NULL;
593 m_IsEventSended =
false;
598 mi = wpn.GetCurrentMuzzle();
600 switch (m_PendingWeaponAction)
604 if ( !ctx.Read(mag) )
610 slotID = wpn.GetSlotFromMuzzleIndex(mi);
612 il.SetAttachment(wpn,mag,slotID);
613 if(
GetGame().AddInventoryJunctureEx(
m_player, mag, il,
false, 10000) )
616 m_PendingTargetMagazine = mag;
621 if ( !ctx.Read(mag) )
625 if (!il.ReadFromContext(ctx))
631 if ( !wpn.GetMagazine(mi) )
636 m_PendingInventoryLocation = il;
637 m_PendingTargetMagazine = mag;
644 if ( !il.ReadFromContext(ctx) )
653 Magazine det_mag = wpn.GetMagazine(mi);
654 mag = Magazine.Cast(il.GetItem());
655 if ( !det_mag || ( mag != det_mag) )
658 if(
GetGame().AddInventoryJunctureEx(
m_player, il.GetItem(), il,
true, 10000))
660 m_PendingInventoryLocation = il;
661 m_PendingTargetMagazine = mag;
673 m_PendingTargetMagazine = mag;
685 m_PendingTargetMagazine = mag;
705 Error(
"unknown actionID=" + m_PendingWeaponAction);
719 m_ControlAction =
ActionBase.Cast(control_action);
720 m_PendingWeaponAction = action;
722 m_IsEventSended =
false;
723 m_PendingTargetMagazine = mag;
724 m_PendingInventoryLocation = il;
725 StartPendingAction();
736 if ( !InventoryReservation(mag, il) )
739 m_PendingWeaponAction = action;
741 m_IsEventSended =
false;
743 if ( !
GetGame().IsMultiplayer() )
744 m_readyToStart =
true;
751 void StartPendingAction()
759 switch (m_PendingWeaponAction)
763 m_player.GetDayZPlayerInventory().PostWeaponEvent(
new WeaponEventAttachMagazine(
m_player, m_PendingTargetMagazine) );
768 m_player.GetDayZPlayerInventory().PostWeaponEvent(
new WeaponEventSwapMagazine(
m_player, m_PendingTargetMagazine, m_PendingInventoryLocation) );
773 Magazine mag = Magazine.Cast(m_PendingInventoryLocation.GetItem());
774 m_player.GetDayZPlayerInventory().PostWeaponEvent(
new WeaponEventDetachMagazine(
m_player, mag, m_PendingInventoryLocation) );
779 m_WantContinue =
false;
780 m_player.GetDayZPlayerInventory().PostWeaponEvent(
new WeaponEventLoad1Bullet(
m_player, m_PendingTargetMagazine) );
785 m_player.GetDayZPlayerInventory().PostWeaponEvent(
new WeaponEventLoad1Bullet(
m_player, m_PendingTargetMagazine) );
790 m_player.GetDayZPlayerInventory().PostWeaponEvent(
new WeaponEventContinuousLoadBulletEnd(
m_player) );
795 m_player.GetDayZPlayerInventory().PostWeaponEvent(
new WeaponEventUnjam(
m_player, NULL) );
800 m_player.GetDayZPlayerInventory().PostWeaponEvent(
new WeaponEventMechanism(
m_player, NULL) );
805 m_player.GetDayZPlayerInventory().PostWeaponEvent(
new WeaponEventSetNextMuzzleMode(
m_player, NULL) );
809 m_InProgress =
false;
810 Error(
"unknown actionID=" + m_PendingWeaponAction);
812 m_IsEventSended =
true;
821 void SetRunning(
bool value)
823 m_InProgress = value;
831 void Update(
float deltaT )
833 if (m_WeaponInHand !=
m_player.GetItemInHands())
837 m_SuitableMagazines.Clear();
841 if ( m_WeaponInHand )
843 m_MagazineInHand =
null;
845 SetSutableMagazines();
846 m_WeaponInHand.SetSyncJammingChance(0);
848 m_AnimationRefreshCooldown = 0;
853 if(m_AnimationRefreshCooldown)
855 m_AnimationRefreshCooldown--;
857 if( m_AnimationRefreshCooldown == 0)
859 RefreshAnimationState();
863 if (!
GetGame().IsMultiplayer())
865 m_WeaponInHand.SetSyncJammingChance(m_WeaponInHand.GetChanceToJam());
869 if ( m_NewJamChance >= 0)
871 m_WeaponInHand.SetSyncJammingChance(m_NewJamChance);
873 m_WaitToSyncJamChance =
false;
875 if (
GetGame().IsServer() && !m_WaitToSyncJamChance )
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 )
882 m_WaitToSyncJamChance =
true;
889 StartPendingAction();
890 m_readyToStart =
false;
894 if( !m_InProgress || !m_IsEventSended )
899 if(m_WeaponInHand.IsIdle())
905 m_InIronSight =
m_player.IsInIronsights();
908 if(m_InIronSight || m_InOptic)
926 if ( m_MagazineInHand !=
m_player.GetItemInHands() )
928 m_MagazineInHand = MagazineStorage.Cast(
m_player.GetItemInHands());
929 if ( m_MagazineInHand )
931 SetSutableMagazines();
939 void OnWeaponActionEnd()
944 if (!m_ControlAction)
948 if(m_PendingTargetMagazine)
957 m_player.GetInventory().ClearInventoryReservationEx(
m_player.GetItemInHands(),il);
959 if( m_PendingTargetMagazine )
961 m_player.GetInventory().ClearInventoryReservationEx(m_PendingTargetMagazine, m_TargetInventoryLocation );
964 if( m_PendingInventoryLocation )
966 m_player.GetInventory().ClearInventoryReservationEx( m_PendingInventoryLocation.GetItem(), m_PendingInventoryLocation );
971 m_ControlAction = NULL;
972 m_PendingWeaponAction = -1;
973 m_PendingTargetMagazine = NULL;
974 m_PendingInventoryLocation = NULL;
975 m_TargetInventoryLocation = NULL;
976 m_PendingWeaponActionAcknowledgmentID = -1;
978 m_InProgress =
false;
979 m_readyToStart =
false;
980 m_WantContinue =
true;
984 void DelayedRefreshAnimationState(
int delay)
990 RefreshAnimationState();
992 m_AnimationRefreshCooldown = delay;
996 void RefreshAnimationState()
1007 hcw.SetInitState(state.m_animState);
1015 return m_WantContinue;
1018 Magazine GetPreparedMagazine()
1020 for (
int i = 0; i < m_SuitableMagazines.Count(); i++)
1022 if(!m_SuitableMagazines.Get(i) || m_SuitableMagazines.Get(i).IsRuined() )
1024 m_SuitableMagazines.Remove(i);
1028 if (m_SuitableMagazines.Get(i).GetAmmoCount() > 0)
1029 return m_SuitableMagazines.Get(i);
1035 Magazine GetNextPreparedMagazine( out
int startIdx )
1037 for (
int i = startIdx; i < m_SuitableMagazines.Count(); i++)
1039 if (m_SuitableMagazines.Get(i).GetAmmoCount() > 0)
1042 return m_SuitableMagazines.Get(i);
1048 void OnMagazineInventoryEnter(Magazine mag)
1059 MagazineStorage sMag = MagazineStorage.Cast(mag);
1062 for(i = 0; i < m_MagazineStorageInInventory.Count(); i++ )
1064 MagazineStorage s_mag_i = m_MagazineStorageInInventory[i];
1067 m_MagazineStorageInInventory.RemoveOrdered(i);
1072 if(CompareMagazinesSuitability(s_mag_i,sMag)<0)
1075 m_MagazineStorageInInventory.InsertAt(sMag,i);
1077 SetSutableMagazines();
1084 for(i = 0; i < m_MagazinePilesInInventory.Count(); i++ )
1086 Magazine mag_i = m_MagazinePilesInInventory[i];
1089 m_MagazinePilesInInventory.RemoveOrdered(i);
1095 if(CompareMagazinesSuitability(mag_i,mag)<0)
1100 m_MagazinePilesInInventory.InsertAt(mag,i);
1101 SetSutableMagazines();
1106 void OnMagazineInventoryExit(Magazine mag)
1108 m_SuitableMagazines.RemoveItem(mag);
1110 MagazineStorage sMag = MagazineStorage.Cast(mag);
1113 m_MagazineStorageInInventory.RemoveItem(sMag);
1119 m_MagazinePilesInInventory.RemoveItem(mag);
1123 void OnMagazineAttach(Magazine mag)
1125 OnMagazineInventoryExit(mag);
1128 void OnMagazineDetach(Magazine mag)
1130 OnMagazineInventoryEnter(mag);
1133 int CompareMagazinesSuitability( Magazine mag1, Magazine mag2 )
1135 return mag1.GetAmmoCount() - mag2.GetAmmoCount();
1138 void SortMagazineAfterLoad()
1142 int low_mag1, high_mag1;
1143 int low_mag2, high_mag2;
1146 for(i = 0; i < m_MagazineStorageInInventory.Count(); i++ )
1148 MagazineStorage mag = m_MagazineStorageInInventory.Get(i);
1149 mag.GetNetworkID(low_mag1,high_mag1);
1150 for( j = 0; j < magazines.Count(); j++)
1152 magazines.Get(j).GetNetworkID(low_mag2,high_mag2);
1153 if(low_mag1 > low_mag2)
1157 else if (low_mag1 == low_mag2)
1159 if( high_mag1 > high_mag2 )
1165 magazines.InsertAt(mag,j);
1168 m_MagazineStorageInInventory.Clear();
1169 m_MagazineStorageInInventory.Copy(magazines);
1171 for(i = 0; i < m_MagazinePilesInInventory.Count(); i++ )
1173 Magazine pile = m_MagazinePilesInInventory.Get(i);
1174 pile.GetNetworkID(low_mag1,high_mag1);
1175 for( j = 0; j < magazines_piles.Count(); j++)
1177 magazines_piles.Get(j).GetNetworkID(low_mag2,high_mag2);
1178 if(low_mag1 > low_mag2)
1182 else if (low_mag1 == low_mag2)
1184 if( high_mag1 > high_mag2 )
1190 magazines_piles.InsertAt(pile,j);
1193 m_MagazinePilesInInventory.Clear();
1194 m_MagazinePilesInInventory.Copy(magazines_piles);
1196 SetSutableMagazines();
1199 void SetSutableMagazines()
1201 m_SuitableMagazines.Clear();
1206 int mi = m_WeaponInHand.GetCurrentMuzzle();
1208 for (i = 0; i < m_MagazineStorageInInventory.Count(); i++ )
1210 MagazineStorage s_mag = m_MagazineStorageInInventory[i];
1214 m_MagazineStorageInInventory.RemoveOrdered(i);
1219 if ( m_WeaponInHand.TestAttachMagazine(mi, s_mag,
false,
true))
1220 m_SuitableMagazines.Insert(s_mag);
1223 for (i = 0; i < m_MagazinePilesInInventory.Count(); i++ )
1225 Magazine mag = m_MagazinePilesInInventory[i];
1228 m_MagazinePilesInInventory.RemoveOrdered(i);
1233 if (m_WeaponInHand.CanChamberFromMag(mi, mag))
1234 m_SuitableMagazines.Insert(mag);
1238 else if (m_MagazineInHand)
1240 for (i = 0; i < m_MagazinePilesInInventory.Count(); i++ )
1242 Magazine m_mag = m_MagazinePilesInInventory[i];
1245 m_MagazinePilesInInventory.RemoveOrdered(i);
1249 if (m_MagazineInHand.IsCompatiableAmmo( m_mag ))
1250 m_SuitableMagazines.Insert(m_mag);
1255 m_PreparedMagazine =
null;
1262 if( m_WeaponInHand )
1263 m_WeaponInHand.ResetBurstCount();
1266 string GetCurrentModeName()
1268 if( m_WeaponInHand )
1270 int mi = m_WeaponInHand.GetCurrentMuzzle();
1271 return m_WeaponInHand.GetCurrentModeName(mi);
1278 int muzzleIndex = wpn.GetCurrentMuzzle();
1279 Magazine old_mag = Magazine.Cast(wpn.GetMagazine(muzzleIndex));
1284 bool result =
GameInventory.CanSwapEntitiesEx(new_mag, old_mag);
1287 new_mag.GetInventory().GetCurrentInventoryLocation(new_il);
1288 new_il.SetItem(old_mag);
1292 result =
GameInventory.CanForceSwapEntitiesEx(new_mag,
null, old_mag, new_il);
1296 new_il.SetGroundEx( old_mag,
m_player.GetPosition(), dir);