DayZ Scripts
v1.21.156300 · Jun 20, 2023
 
Loading...
Searching...
No Matches
Weapon_Base.c
Go to the documentation of this file.
1
5{
6 int m_action;
8 void AbilityRecord (int a, int at) { m_action = a; m_actionType = at; }
9};
10
11enum WeaponWithAmmoFlags
12{
14 NONE = 0,
29}
30
32
38class Weapon_Base extends Weapon
39{
41 const int SAMF_DEFAULT = WeaponWithAmmoFlags.CHAMBER | WeaponWithAmmoFlags.MAX_CAPACITY_MAG;
43 const int SAMF_RNG = WeaponWithAmmoFlags.CHAMBER_RNG | WeaponWithAmmoFlags.QUANTITY_RNG;
44
45 protected const float DEFAULT_DAMAGE_ON_SHOT = 0.05;
46 protected ref array<ref AbilityRecord> m_abilities = new array<ref AbilityRecord>;
47 protected ref WeaponFSM m_fsm;
48 protected bool m_isJammed = false;
49 protected bool m_LiftWeapon = false;
50 protected bool m_BayonetAttached;
51 protected bool m_ButtstockAttached;
52 protected int m_BurstCount;
55 protected int m_weaponAnimState = -1;
56 protected int m_magazineSimpleSelectionIndex = -1;
57 protected int m_weaponHideBarrelIdx = -1; //index in simpleHiddenSelections cfg array
58 protected float m_DmgPerShot = 0; //default is set to zero, since C++ solution has been implemented. See 'damageBarrel' and 'barrelArmor' in configs.
59 protected float m_WeaponLength;
60 ref array<int> m_bulletSelectionIndex = new array<int>;
62 ref array<float> m_ChanceToJam = new array<float>;
63 protected float m_ChanceToJamSync = 0;
66
68 {
69 //m_DmgPerShot = ConfigGetFloat("damagePerShot");
70 m_BayonetAttached = false;
71 m_ButtstockAttached = false;
72 m_BayonetAttachmentIdx = -1;
73 m_ButtstockAttachmentIdx = -1;
74 m_BurstCount = 0;
75 m_DOFProperties = new array<float>;
76
77 if ( ConfigIsExisting("simpleHiddenSelections") )
78 {
79 TStringArray selectionNames = new TStringArray;
80 ConfigGetTextArray("simpleHiddenSelections",selectionNames);
81 m_weaponHideBarrelIdx = selectionNames.Find("hide_barrel");
82 m_magazineSimpleSelectionIndex = selectionNames.Find("magazine");
83
84 int bulletIndex = selectionNames.Find("bullet");
85 if ( bulletIndex != -1 )
86 {
87 m_bulletSelectionIndex.Insert(bulletIndex);
88
89 for (int i = 2; i < 100; i++)
90 {
91 bulletIndex = selectionNames.Find(string.Format("bullet%1",i));
92 if (bulletIndex != -1)
93 {
94 m_bulletSelectionIndex.Insert(bulletIndex);
95 }
96 else
97 {
98 break;
99 }
100 }
101 }
102 }
103
104 InitWeaponLength();
105 InitDOFProperties(m_DOFProperties);
106 if (GetGame().IsServer())
107 {
108 InitReliability(m_ChanceToJam);
109 }
111 }
112
114
115 override void EEInit()
116 {
117 super.EEInit();
118
120 }
121
123 {
124 m_fsm.SetInitialState(initState);
125 SetGroundAnimFrameIndex(initState.m_animState);
126 }
127
128 override protected float GetWeightSpecialized(bool forceRecalc = false)
129 {
130 float baseWeight = GetInventoryAndCargoWeight(forceRecalc);
131 float ammoWeight;
132 float ammoDamage;
133 string bulletTypeName, ammoTypeName;
134
135 int muzzleCount = GetMuzzleCount();
136 #ifdef DEVELOPER
137 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
138 {
139 WeightDebugData data1 = WeightDebug.GetWeightDebug(this);
140 data1.SetCalcDetails("TWPN: " + m_ConfigWeight+"(item weight) + " + baseWeight +"(contents weight)" );
141 }
142 #endif
143 for (int muzzleIndex = 0; muzzleIndex < muzzleCount; muzzleIndex++)
144 {
145 //chamber weight
146 if (!IsChamberEmpty(muzzleIndex))
147 {
148 ammoTypeName = GetChamberAmmoTypeName(muzzleIndex);
149 ammoWeight += g_Game.ConfigGetFloat(string.Format("CfgMagazines %1 weight", ammoTypeName));
150
151 #ifdef DEVELOPER
152 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
153 {
154 WeightDebugData data2 = WeightDebug.GetWeightDebug(this);
155 data2.AddCalcDetails( g_Game.ConfigGetFloat("CfgMagazines " + ammoTypeName + " weight").ToString() +"(chamber weight)");
156 }
157 #endif
158 }
159
160 //correctly calculates internal magazine weight based on the ammo type of each bullet
161 if (HasInternalMagazine(muzzleIndex))
162 {
163 #ifdef DEVELOPER
164 float debugInternalMagWeight;
165 #endif
166 int cartridgeCount = GetInternalMagazineCartridgeCount(muzzleIndex);
167 for (int cartridgeIndex = 0; cartridgeIndex < cartridgeCount; cartridgeIndex++)
168 {
169 GetInternalMagazineCartridgeInfo(muzzleIndex, cartridgeIndex, ammoDamage, bulletTypeName);
170 ammoWeight += Ammunition_Base.GetAmmoWeightByBulletType(bulletTypeName);
171 #ifdef DEVELOPER
172 debugInternalMagWeight += g_Game.ConfigGetFloat("CfgMagazines " + ammoTypeName + " weight");
173 #endif
174 }
175 #ifdef DEVELOPER
176
177 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
178 {
179 WeightDebugData data3 = WeightDebug.GetWeightDebug(this);
180 data3.AddCalcDetails(debugInternalMagWeight.ToString()+ "(internal mag weight)");
181 }
182 #endif
183 }
184
185 }
186 return ammoWeight + baseWeight + GetConfigWeightModified();
187 }
190
191 bool CanProcessAction(int action, int actionType)
192 {
193 return false; // @TODO
194 }
201 bool HasActionAbility(int action, int actionType)
202 {
203 int count = GetAbilityCount();
204 for (int i = 0; i < count; ++i)
205 {
206 AbilityRecord rec = GetAbility(i);
207 if (rec.m_action == action && rec.m_actionType == actionType)
208 return true;
209 }
210 return false;
211 }
215 int GetAbilityCount() { return m_abilities.Count(); }
220 AbilityRecord GetAbility(int index) { return m_abilities.Get(index); }
221
225 bool CanProcessWeaponEvents() { return m_fsm && m_fsm.IsRunning(); }
226
231 WeaponStateBase GetCurrentState() { return m_fsm.GetCurrentState(); }
232
237 {
238 return CanProcessWeaponEvents() && GetCurrentState().IsWaitingForActionFinish();
239 }
240
241 bool IsIdle()
242 {
243 return CanProcessWeaponEvents() && GetCurrentState().IsIdle();
244 }
245
251 {
252 SyncEventToRemote(e);
253
254 // @NOTE: synchronous events not handled by fsm
255 if (e.GetEventID() == WeaponEventID.SET_NEXT_MUZZLE_MODE)
256 {
257 SetNextMuzzleMode(GetCurrentMuzzle());
258 return true;
259 }
260
261 if (m_fsm.ProcessEvent(e) == ProcessEventResult.FSM_OK)
262 return true;
263
264 //if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("FSM refused to process event (no transition): src=" + GetCurrentState().ToString() + " event=" + e.ToString()); }
265 return false;
266 }
271 {
272 SyncEventToRemote(e);
273
275 m_fsm.ProcessAbortEvent(e, aa);
276 return aa == ProcessEventResult.FSM_OK;
277 }
278
279 bool CanChamberBullet(int muzzleIndex, Magazine mag)
280 {
281 return CanChamberFromMag(muzzleIndex, mag) && (!IsChamberFull(muzzleIndex) || IsChamberFiredOut(muzzleIndex) || !IsInternalMagazineFull(muzzleIndex));
282 }
283
284 void SetWeaponAnimState(int state)
285 {
286 m_weaponAnimState = state;
287 SetGroundAnimFrameIndex(state);
288 }
290 {
291 fsmDebugSpam("[wpnfsm] " + Object.GetDebugName(this) + " resetting anim state: " + typename.EnumToString(PistolAnimState, m_weaponAnimState) + " --> " + typename.EnumToString(PistolAnimState, -1));
292 m_weaponAnimState = -1;
293 }
294 int GetWeaponAnimState() { return m_weaponAnimState; }
295
296 void EEFired(int muzzleType, int mode, string ammoType)
297 {
298 if ( !GetGame().IsDedicatedServer() )
299 {
300 ItemBase suppressor = GetAttachedSuppressor();
301
302 // Muzzle flash & overheating effects
303 ItemBase.PlayFireParticles(this, muzzleType, ammoType, this, suppressor, "CfgWeapons" );
304 IncreaseOverheating(this, ammoType, this, suppressor, "CfgWeapons");
305
306 if (suppressor)
307 {
308 ItemBase.PlayFireParticles(this, muzzleType, ammoType, suppressor, NULL, "CfgVehicles" );
309 suppressor.IncreaseOverheating(this, ammoType, this, suppressor, "CfgVehicles");
310 }
311 }
312
313 //obsolete, replaced by C++ solution!
314/*
315 if (GetGame().IsServer())
316 {
317 AddHealth("","Health",-m_DmgPerShot); //damages weapon
318 if (suppressor)
319 suppressor.AddHealth("","Health",-m_DmgPerShot); //damages suppressor; TODO add suppressor damage coeficient/parameter (?) to suppressors/weapons (?)
320 }
321*/
322 //JamCheck(muzzleType);
323
324 #ifdef DIAG_DEVELOPER
325 MiscGameplayFunctions.UnlimitedAmmoDebugCheck(this);
326 #endif
327 }
328
329 bool JamCheck(int muzzleIndex )
330 {
331 PlayerBase player = PlayerBase.Cast(GetHierarchyRootPlayer());
332 if ( player )
333 {
334 float rnd = player.GetRandomGeneratorSyncManager().GetRandom01(RandomGeneratorSyncUsage.RGSJam);
335 //Print("Random Jam - " + rnd);
336 if (rnd < GetSyncChanceToJam())
337 return true;
338 }
339 return false;
340 }
341
342 void ShowBullet(int muzzleIndex)
343 {
344 if ( m_bulletSelectionIndex.Count() > muzzleIndex )
345 {
346 SetSimpleHiddenSelectionState(m_bulletSelectionIndex[muzzleIndex],1);
347 }
348 else
349 SelectionBulletShow();
350 }
351
352 void HideBullet(int muzzleIndex)
353 {
354 if ( m_bulletSelectionIndex.Count() > muzzleIndex )
355 {
356 SetSimpleHiddenSelectionState(m_bulletSelectionIndex[muzzleIndex],0);
357 }
358 else
359 SelectionBulletHide();
360 }
361
362 bool IsJammed() { return m_isJammed; }
363 bool CanEjectBullet() {return true;}
364 void SetJammed(bool value) { m_isJammed = value; }
365 float GetSyncChanceToJam() { return m_ChanceToJamSync; }
367 {
368 int level = GetHealthLevel();
369
370 if (level >= 0 && level < m_ChanceToJam.Count())
371 return m_ChanceToJam[level];
372 else
373 return 0.0;
374 }
375
376 void SyncSelectionState(bool has_bullet, bool has_mag)
377 {
378 if (has_bullet)
379 SelectionBulletShow();
380 else
381 SelectionBulletHide();
382
383 if (has_mag)
384 ShowMagazine();
385 else
386 HideMagazine();
387 }
388
390 {
391 int nMuzzles = GetMuzzleCount();
392 for (int i = 0; i < nMuzzles; ++i)
393 {
394 if (IsChamberFull(i))
395 {
396 ShowBullet(i);
397 float damage;
398 string ammoTypeName;
399 GetCartridgeInfo(i, damage, ammoTypeName);
400 EffectBulletShow(i, damage, ammoTypeName);
401 }
402 else
403 {
404 HideBullet(i);
405 EffectBulletHide(i);
406 }
407
408 Magazine mag = GetMagazine(i);
409 if (mag)
410 ShowMagazine();
411 else
412 HideMagazine();
413 }
414 }
415
416 override bool OnStoreLoad(ParamsReadContext ctx, int version)
417 {
418 if ( !super.OnStoreLoad(ctx, version) )
419 return false;
420
421
422 if (version >= 113)
423 {
424 int current_muzzle = 0;
425 if (!ctx.Read(current_muzzle))
426 {
427 Error("Weapon.OnStoreLoad " + this + " cannot read current muzzle!");
428 return false;
429 }
430
431 if (current_muzzle >= GetMuzzleCount() || current_muzzle < 0)
432 Error("Weapon.OnStoreLoad " + this + " trying to set muzzle index " + current_muzzle + " while it only has " + GetMuzzleCount() + " muzzles!");
433 else
434 SetCurrentMuzzle(current_muzzle);
435 }
436
437 if (version >= 105)
438 {
439 int mode_count = 0;
440 if (!ctx.Read(mode_count))
441 {
442 Error("Weapon.OnStoreLoad " + this + " cannot read mode count!");
443 return false;
444 }
445
446 for (int m = 0; m < mode_count; ++m)
447 {
448 int mode = 0;
449 if (!ctx.Read(mode))
450 {
451 Error("Weapon.OnStoreLoad " + this + " cannot read mode[" + m + "]");
452 return false;
453 }
454
455 if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(this) + " OnStoreLoad - loaded muzzle[" + m + "].mode = " + mode); }
456 SetCurrentMode(m, mode);
457 }
458 }
459
460 if ( version >= 106 )
461 {
462 if ( !ctx.Read(m_isJammed) )
463 {
464 Error("Weapon.OnStoreLoad cannot load jamming state");
465 return false;
466 }
467 }
468
469 if (m_fsm)
470 {
471 if (!m_fsm.OnStoreLoad(ctx, version))
472 return false;
473
474 WeaponStableState wss = WeaponStableState.Cast(m_fsm.GetCurrentState());
475 if (wss)
476 {
477 SetGroundAnimFrameIndex(wss.m_animState);
478 }
479
480 }
481 else
482 {
483 int dummy = 0;
484 if (!ctx.Read(dummy))
485 return false;
486 }
487
488 return true;
489 }
490
492 {
493 if (m_fsm && m_fsm.IsRunning())
494 {
495 if (m_fsm.SaveCurrentFSMState(ctx))
496 {
497 if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(this) + " Weapon=" + this + " state saved."); }
498 }
499 else
500 Error("[wpnfsm] " + Object.GetDebugName(this) + " Weapon=" + this + " state NOT saved.");
501 }
502 else
503 Error("[wpnfsm] " + Object.GetDebugName(this) + " Weapon.SaveCurrentFSMState: trying to save weapon without FSM (or uninitialized weapon) this=" + this + " type=" + GetType());
504 }
505
507 {
508 if (m_fsm)
509 {
510 if (m_fsm.LoadCurrentFSMState(ctx, version))
511 {
512 WeaponStableState state = WeaponStableState.Cast(GetCurrentState());
513 if (state)
514 {
515 SyncSelectionState(state.HasBullet(), state.HasMagazine());
516 state.SyncAnimState();
517 if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(this) + " Weapon=" + this + " stable state loaded and synced."); }
518 return true;
519 }
520 else
521 {
522 if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(this) + " Weapon=" + this + " unstable/error state loaded."); }
523 return false;
524 }
525 }
526 else
527 {
528 Error("[wpnfsm] " + Object.GetDebugName(this) + " Weapon=" + this + " did not load.");
529 return false;
530 }
531 }
532 else
533 {
534 Error("[wpnfsm] " + Object.GetDebugName(this) + " Weapon.LoadCurrentFSMState: trying to load weapon without FSM (or uninitialized weapon) this=" + this + " type=" + GetType());
535 return false;
536 }
537 }
538
539 override void AfterStoreLoad()
540 {
541 if (m_fsm)
542 {
543 int mi = GetCurrentMuzzle();
544 Magazine mag = GetMagazine(mi);
545 bool has_mag = mag != null;
546 bool has_bullet = !IsChamberEmpty(mi);
547 SyncSelectionState(has_bullet, has_mag);
548 }
549 }
550
552 {
553 super.OnStoreSave(ctx);
554
555 // current muzzle added in version 113
556 int current_muzzle = GetCurrentMuzzle();
557 ctx.Write(current_muzzle);
558
559 // fire mode added in version 105
560 int mode_count = GetMuzzleCount();
561 ctx.Write(mode_count);
562 for (int m = 0; m < mode_count; ++m)
563 ctx.Write(GetCurrentMode(m));
564
565 ctx.Write(m_isJammed);
566
567 if (m_fsm)
568 m_fsm.OnStoreSave(ctx);
569 else
570 {
571 int dummy = 0;
572 ctx.Write(dummy);
573 }
574 }
575
580 {
581 if (m_fsm)
582 return m_fsm.GetInternalStateID();
583 return 0;
584 }
585
590 {
591 if (m_fsm)
592 {
593 return m_fsm.GetCurrentStableStateID();
594 }
595 return 0;
596 }
597
603 {
604 if (m_fsm)
605 {
606 int mi = GetCurrentMuzzle();
607 Magazine mag = GetMagazine(mi);
608 bool has_mag = mag != null;
609 bool has_bullet = !IsChamberEmpty(mi);
610 bool has_jam = IsJammed();
611 array<MuzzleState> muzzleStates = GetMuzzleStates();
612 m_fsm.RandomizeFSMStateEx(muzzleStates, has_mag, has_jam);
613 ForceSyncSelectionState();
614 }
615 }
616
619 {
620 array<MuzzleState> muzzleStates = new array<MuzzleState>;
621
622 int nMuzzles = GetMuzzleCount();
623 for (int i = 0; i < nMuzzles; ++i)
624 {
625 MuzzleState state = MuzzleState.U;
626 if (IsChamberFiredOut(i))
627 state = MuzzleState.F;
628 else if (IsChamberFull(i))
629 state = MuzzleState.L;
630 else if (IsChamberEmpty(i))
631 state = MuzzleState.E;
632 else
633 ErrorEx(string.Format("Unable to identify chamber state of muzzle %1", i));
634
635 muzzleStates.Insert(state);
636 }
637
638 return muzzleStates;
639 }
640
647
655 static Weapon_Base CreateWeaponWithAmmo( string weaponType, string magazineType = "", int flags = WeaponWithAmmoFlags.CHAMBER )
656 {
657 Weapon_Base wpn = Weapon_Base.Cast(GetGame().CreateObjectEx( weaponType, vector.Zero, ECE_PLACE_ON_SURFACE ));
658
659 if ( !wpn )
660 {
661 ErrorEx(string.Format("%1 does not exist or is not a weapon.", weaponType));
662 return null;
663 }
664
665 wpn.SpawnAmmo(magazineType, flags);
666 return wpn;
667 }
668
675 bool SpawnAmmo( string magazineType = "", int flags = WeaponWithAmmoFlags.CHAMBER )
676 {
677 // Attempt internal mag
678 if ( HasInternalMagazine(-1) && FillInnerMagazine(magazineType, flags) )
679 return true;
680
681 // Attempt mag attachment
682 if ( GetMagazineTypeCount(0) > 0 && SpawnAttachedMagazine(magazineType, flags) )
683 return true;
684
685 // Attempt chamber
686 if ( FillChamber(magazineType, flags) )
687 return true;
688
689 return false;
690 }
691
698 Magazine SpawnAttachedMagazine( string magazineType = "", int flags = WeaponWithAmmoFlags.CHAMBER )
699 {
700 // Check if the gun has any magazines registered in config
701 if ( GetMagazineTypeCount(0) == 0 )
702 {
703 ErrorEx(string.Format("No 'magazines' config entry for %1.", this));
704 return null;
705 }
706
707 // Randomize when no specific one is given
708 if ( magazineType == "" )
709 {
710 if ( flags & WeaponWithAmmoFlags.MAX_CAPACITY_MAG)
711 magazineType = GetMaxMagazineTypeName(0);
712 else
713 magazineType = GetRandomMagazineTypeName(0);
714 }
715
716 EntityAI magAI = GetInventory().CreateAttachment(magazineType);
717 if (!magAI)
718 {
719 ErrorEx(string.Format("Failed to create and attach %1 to %2", GetDebugName(magAI), this));
720 return null;
721 }
722
723 Magazine mag;
724 if (!CastTo(mag, magAI))
725 {
726 ErrorEx(string.Format("Expected magazine, created: %1", GetDebugName(magAI)));
727 return null;
728 }
729
730 // Decide random quantity when enabled
731 if (flags & WeaponWithAmmoFlags.QUANTITY_RNG)
732 mag.ServerSetAmmoCount(Math.RandomIntInclusive(0, mag.GetAmmoMax()));
733
734 // Fill chamber when flagged
735 bool chamberRng = (flags & WeaponWithAmmoFlags.CHAMBER_RNG);
736 bool chamber = (flags & WeaponWithAmmoFlags.CHAMBER) || chamberRng;
737 if (chamber || chamberRng)
738 {
739 FillChamber(magazineType, flags);
740 }
741
742 // FSM cares about magazine state
743 RandomizeFSMState();
744 Synchronize();
745
746 return mag;
747 }
748
756 bool FillInnerMagazine( string ammoType = "", int flags = WeaponWithAmmoFlags.CHAMBER )
757 {
758 // Don't try to fill it when there are none
759 if (!HasInternalMagazine(-1))
760 return false;
761
762 // Make sure the given ammoType is actually useable
763 if (ammoType != "")
764 {
765 if (!AmmoTypesAPI.MagazineTypeToAmmoType(ammoType, ammoType))
766 return false;
767 }
768
769
770 bool didSomething = false;
771 int muzzCount = GetMuzzleCount();
772
773 bool ammoRng = ammoType == "";
774 bool ammoFullRng = ammoRng && (flags & WeaponWithAmmoFlags.AMMO_MAG_RNG);
775
776 // No full RNG flag, so pick one random and use only this one
777 if (ammoRng && !ammoFullRng)
778 ammoType = GetRandomChamberableAmmoTypeName(0);
779
780 // Fill the internal magazine
781 for (int i = 0; i < muzzCount; ++i)
782 {
783 int ammoCount = GetInternalMagazineMaxCartridgeCount(i);
784
785 // Decide random quantity when enabled
786 if ( flags & WeaponWithAmmoFlags.QUANTITY_RNG )
787 ammoCount = Math.RandomIntInclusive(0, ammoCount);
788
789 // Only do the things when there is actually ammo to fill
790 if (ammoCount > 0)
791 {
792 // Push in the cartridges
793 for (int j = 0; j < ammoCount; ++j)
794 {
795 // Full random, decide a new one for every cartridge
796 if ( ammoFullRng )
797 ammoType = GetRandomChamberableAmmoTypeName(i);
798
799 PushCartridgeToInternalMagazine(i, 0, ammoType);
800 didSomething = true;
801 }
802 }
803 }
804
805 // Call the chamber method if asked for
806 bool chamber = (flags & WeaponWithAmmoFlags.CHAMBER) || (flags & WeaponWithAmmoFlags.CHAMBER_RNG);
807 if (chamber && FillChamber(ammoType, flags))
808 {
809 didSomething = true;
810 }
811
812 // Does not need any FSM fixing, FSM does not care about inner magazines
813
814 return didSomething;
815 }
816
824 bool FillChamber( string ammoType = "", int flags = WeaponWithAmmoFlags.CHAMBER )
825 {
826 // Quickly check if there are any chambers we can fill
827 int muzzCount = GetMuzzleCount();
828 bool anyEmpty = false;
829
830 for (int m = 0; m < muzzCount; ++m)
831 {
832 if (IsChamberEmpty(m))
833 {
834 anyEmpty = true;
835 break;
836 }
837 }
838
839 if (!anyEmpty)
840 return false;
841
842 // Make sure the given ammoType is actually useable
843 if (ammoType != "")
844 if (!AmmoTypesAPI.MagazineTypeToAmmoType(ammoType, ammoType))
845 return false;
846
847 // Just so we don't '&' wastefully in a loop
848 bool didSomething = false;
849 bool chamberFullRng = (flags & WeaponWithAmmoFlags.CHAMBER_RNG_SPORADIC);
850 bool chamberRng = (flags & WeaponWithAmmoFlags.CHAMBER_RNG);
851 bool chamber = (flags & WeaponWithAmmoFlags.CHAMBER);
852
853 if (chamber || chamberRng || chamberFullRng)
854 {
855 int amountToChamber = muzzCount;
856
857 // No need to do this for full rng, as that will roll for every muzzle
858 if (chamberRng)
859 amountToChamber = Math.RandomIntInclusive(0, muzzCount);
860
861 bool chamberAmmoRng = (ammoType == "");
862 bool chamberAmmoFullRng = chamberAmmoRng && (flags & WeaponWithAmmoFlags.AMMO_CHAMBER_RNG);
863
864 // No full RNG flag, so pick one random and use only this one
865 if (chamberAmmoRng && !chamberAmmoFullRng)
866 ammoType = GetRandomChamberableAmmoTypeName(0);
867
868 for (int i = 0; i < muzzCount; ++i)
869 {
870 // Skip when there's already something in the chamber
871 if (!IsChamberEmpty(i))
872 continue;
873
874 // Roll the rng when enabled
875 if (chamberFullRng)
876 chamber = Math.RandomIntInclusive(0, 1);
877
878 // We chambering
879 if (chamber)
880 {
881 // Full random, decide a new one for every muzzle
882 if ( chamberAmmoFullRng )
883 ammoType = GetRandomChamberableAmmoTypeName(i);
884
885 // Push it
886 PushCartridgeToChamber(i, 0, ammoType);
887 didSomething = true;
888
889 // Stop chambering when we hit the desired amount
890 --amountToChamber;
891 if (amountToChamber <= 0)
892 break;
893 }
894 }
895 }
896
897 // Only fix the FSM and Synchronize when absolutely needed
898 if (!didSomething)
899 return false;
900
901 // FSM cares about chamber state
902 RandomizeFSMState();
903 Synchronize();
904
905 return true;
906 }
907
909
910
911
915 override int GetSlotsCountCorrect()
916 {
917 int ac = GetInventory().AttachmentCount();
918 int sc = GetInventory().GetAttachmentSlotsCount() + GetMuzzleCount();
919 if (ac > sc) sc = ac; // fix of some weapons which has 1 attachments but 0 slots...
920 return sc;
921 };
922
924 {
925 if (!m_PropertyModifierObject)
926 {
927 m_PropertyModifierObject = new PropertyModifiers(this);
928 }
929 return m_PropertyModifierObject;
930 }
931
932 void OnFire(int muzzle_index)
933 {
934/*
935 array<Man> players();
936 GetGame().GetPlayers(players);
937
938 Man root = GetHierarchyRootPlayer();
939
940 if (!root)
941 {
942 return;
943 }
944
945 vector safePosition = root.GetPosition() + (root.GetDirection() * "0 1 0" * 3.0);
946
947 Man other = null;
948 foreach (auto player : players)
949 {
950 if (player != GetHierarchyRootPlayer())
951 {
952 player.SetPosition(safePosition);
953 }
954 }
955*/
956
957 m_BurstCount++;
958 }
959
960 void OnFireModeChange(int fireMode)
961 {
962 if ( !GetGame().IsDedicatedServer() )
963 {
964 EffectSound eff;
965
966 if ( fireMode == 0 )
967 eff = SEffectManager.PlaySound("Fire_Mode_Switch_Marked_Click_SoundSet", GetPosition());
968 else
969 eff = SEffectManager.PlaySound("Fire_Mode_Switch_Simple_Click_SoundSet", GetPosition());
970
971 eff.SetAutodestroy(true);
972 }
973
974 ResetBurstCount();
975 }
976
978 {
979 if ( m_fsm )
980 m_fsm.ValidateAndRepair();
981 }
982
983 override void OnInventoryEnter(Man player)
984 {
985 m_PropertyModifierObject = null;
986
987 ValidateAndRepair();
988
989 super.OnInventoryEnter(player);
990 }
991
992 override void OnInventoryExit(Man player)
993 {
994 m_PropertyModifierObject = null;
995 super.OnInventoryExit(player);
996 }
997
998 override void EEItemAttached(EntityAI item, string slot_name)
999 {
1000 super.EEItemAttached(item, slot_name);
1001
1002 GetPropertyModifierObject().UpdateModifiers();
1003 }
1004
1005 override void EEItemDetached(EntityAI item, string slot_name)
1006 {
1007 super.EEItemDetached(item, slot_name);
1008
1009 GetPropertyModifierObject().UpdateModifiers();
1010 }
1011
1012 override void EEItemLocationChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
1013 {
1014 super.EEItemLocationChanged(oldLoc, newLoc);
1015
1016 if (newLoc.GetType() == InventoryLocationType.HANDS)
1017 {
1018 PlayerBase player;
1019 if (newLoc.GetParent() && PlayerBase.CastTo(player, newLoc.GetParent()))
1020 {
1021 HumanCommandMove cm = player.GetCommand_Move();
1022 if (cm)
1023 {
1024 cm.SetMeleeBlock(false);
1025 }
1026 }
1027 }
1028 }
1029
1030 override void OnItemLocationChanged(EntityAI old_owner, EntityAI new_owner)
1031 {
1032 super.OnItemLocationChanged(old_owner,new_owner);
1033
1034 // "resets" optics memory on optics
1035 PlayerBase player;
1036 if (PlayerBase.CastTo(player,old_owner))
1037 {
1038 player.SetReturnToOptics(false);
1039 }
1040
1041 HideWeaponBarrel(false);
1042 }
1043
1044 override bool CanReleaseAttachment(EntityAI attachment)
1045 {
1046 if ( !super.CanReleaseAttachment( attachment ) )
1047 return false;
1048 Magazine mag = Magazine.Cast(attachment);
1049 if (mag)
1050 {
1051 PlayerBase player = PlayerBase.Cast( GetHierarchyRootPlayer() );
1052 if ( player )
1053 {
1054 if ( player.GetItemInHands() == this )
1055 return true;
1056 }
1057 return false;
1058 }
1059
1060 return true;
1061 }
1062
1063 override bool CanRemoveFromHands(EntityAI parent)
1064 {
1065 if (IsIdle())
1066 {
1067 return true;
1068 }
1069 if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(this) + " Weapon=" + this + " not in stable state=" + GetCurrentState().Type()); }
1070 return false; // do not allow removal of weapon while weapon is busy
1071 }
1072
1074 {
1076 if (GetInventory().GetCurrentInventoryLocation(il))
1077 {
1078 EntityAI parent = il.GetParent();
1079 DayZPlayer dayzp = DayZPlayer.Cast(parent);
1080 if (il.GetType() == InventoryLocationType.HANDS && dayzp)
1081 {
1082 bool remote = dayzp.GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_REMOTE;
1083 return remote;
1084 }
1085 }
1086 return true;
1087 }
1088
1090 {
1091 DayZPlayer p = DayZPlayer.Cast(GetHierarchyParent());
1092 if (p && p.GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
1093 {
1095
1097 e.WriteToContext(ctx);
1098
1100 wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(this) + " send 2 remote: sending e=" + e + " id=" + e.GetEventID() + " p=" + e.m_player + " m=" + e.m_magazine);
1101
1102 p.StoreInputForRemotes(ctx);
1103 }
1104 }
1105
1106
1108 {
1109 return new DefaultRecoil(this);
1110 }
1111
1112 int GetWeaponSpecificCommand(int weaponAction, int subCommand)
1113 {
1114 return subCommand;
1115 }
1116
1117 bool CanFire()
1118 {
1119 if (!IsChamberEmpty(GetCurrentMuzzle()) && !IsChamberFiredOut(GetCurrentMuzzle()) && !IsJammed() && !m_LiftWeapon && !IsDamageDestroyed())
1120 return true;
1121 return false;
1122 }
1123
1125 {
1126 ItemOptics optic = GetAttachedOptics();
1127 if (!optic)
1128 return true;
1129
1130 return optic.HasWeaponIronsightsOverride();
1131 }
1132
1134 bool InitDOFProperties(out array<float> temp_array)
1135 {
1136 if (GetGame().ConfigIsExisting("cfgWeapons " + GetType() + " PPDOFProperties"))
1137 {
1138 GetGame().ConfigGetFloatArray("cfgWeapons " + GetType() + " PPDOFProperties", temp_array);
1139 return true;
1140 }
1141 return false;
1142 }
1143
1144 bool InitReliability(out array<float> reliability_array)
1145 {
1146 if (GetGame().ConfigIsExisting("cfgWeapons " + GetType() + " Reliability ChanceToJam"))
1147 {
1148 GetGame().ConfigGetFloatArray("cfgWeapons " + GetType() + " Reliability ChanceToJam", reliability_array);
1149 return true;
1150 }
1151 return false;
1152 }
1153
1156 {
1157 if (ConfigIsExisting("WeaponLength"))
1158 {
1159 m_WeaponLength = ConfigGetFloat("WeaponLength");
1160 return true;
1161 }
1162 m_WeaponLength = 0.8; //default value if not set in config; should not be zero
1163 return false;
1164 }
1165
1167 {
1168 return m_DOFProperties;
1169 }
1170
1171 // lifting weapon on obstcles
1173 {
1174 int idx;
1175 float distance;
1176 float hit_fraction; //junk
1177 vector start, end;
1178 vector direction;
1179 vector usti_hlavne_position;
1180 vector trigger_axis_position;
1181 vector hit_pos, hit_normal; //junk
1182 Object obj;
1183 ItemBase attachment;
1184 HumanMovementState movementState = new HumanMovementState();
1185
1186 m_LiftWeapon = false;
1187 // not a gun, no weap.raise for now
1188 if ( HasSelection("Usti hlavne") )
1189 return false;
1190
1191 if (!player)
1192 {
1193 Print("Error: No weapon owner, returning");
1194 return false;
1195 }
1196
1197 // weapon not raised
1198 player.GetMovementState(movementState);
1199 if (!movementState.IsRaised())
1200 return false;
1201
1202 usti_hlavne_position = GetSelectionPositionLS( "Usti hlavne" ); // Usti hlavne
1203 trigger_axis_position = GetSelectionPositionLS("trigger_axis");
1204
1205 // freelook raycast
1206 if (player.GetInputController().CameraIsFreeLook())
1207 {
1208 if (player.m_DirectionToCursor != vector.Zero)
1209 {
1210 direction = player.m_DirectionToCursor;
1211 }
1212 // if player raises weapon in freelook
1213 else
1214 {
1215 direction = MiscGameplayFunctions.GetHeadingVector(player);
1216 }
1217 }
1218 else
1219 {
1220 direction = GetGame().GetCurrentCameraDirection(); // exception for freelook. Much better this way!
1221 }
1222
1223 idx = player.GetBoneIndexByName("Neck"); //RightHandIndex1
1224 if ( idx == -1 )
1225 { start = player.GetPosition()[1] + 1.5; }
1226 else
1227 { start = player.GetBonePositionWS(idx); }
1228
1230 /*usti_hlavne_position = ModelToWorld(usti_hlavne_position);
1231 distance = vector.Distance(start,usti_hlavne_position);*/
1232 distance = m_WeaponLength;// - 0.05; //adjusted raycast length
1233
1234 // if weapon has battel attachment, does longer cast
1235 if (ItemBase.CastTo(attachment,FindAttachmentBySlotName("weaponBayonet")) || ItemBase.CastTo(attachment,FindAttachmentBySlotName("weaponBayonetAK")) || ItemBase.CastTo(attachment,FindAttachmentBySlotName("weaponBayonetMosin")) || ItemBase.CastTo(attachment,FindAttachmentBySlotName("weaponBayonetSKS")) || ItemBase.CastTo(attachment,GetAttachedSuppressor()))
1236 {
1237 distance += attachment.m_ItemModelLength;
1238 }
1239 end = start + (direction * distance);
1240 DayZPhysics.RayCastBullet(start, end, hit_mask, player, obj, hit_pos, hit_normal, hit_fraction);
1241
1242 // something is hit
1243 if (hit_pos != vector.Zero)
1244 {
1245 //Print(distance);
1246 m_LiftWeapon = true;
1247 return true;
1248 }
1249 return false;
1250 }
1251
1252 void SetSyncJammingChance( float jamming_chance )
1253 {
1254 m_ChanceToJamSync = jamming_chance;
1255 }
1256
1267 bool EjectCartridge(int muzzleIndex, out float ammoDamage, out string ammoTypeName)
1268 {
1269 if (IsChamberEjectable(muzzleIndex))
1270 {
1271 if (PopCartridgeFromChamber(muzzleIndex, ammoDamage, ammoTypeName))
1272 return true;
1273 }
1274 else if (GetInternalMagazineCartridgeCount(muzzleIndex) > 0)
1275 {
1276 if (PopCartridgeFromInternalMagazine(muzzleIndex, ammoDamage, ammoTypeName))
1277 return true;
1278 }
1279 return false;
1280 }
1281
1283 {
1284 float damage = 0.0;
1285 string type;
1286
1287 for (int mi = 0; mi < src.GetMuzzleCount(); ++mi)
1288 {
1289 if (!src.IsChamberEmpty(mi))
1290 {
1291 if (src.GetCartridgeInfo(mi, damage, type))
1292 {
1293 PushCartridgeToChamber(mi, damage, type);
1294 }
1295 }
1296
1297 for (int ci = 0; ci < src.GetInternalMagazineCartridgeCount(mi); ++ci)
1298 {
1299 if (src.GetInternalMagazineCartridgeInfo(mi, ci, damage, type))
1300 {
1301 PushCartridgeToInternalMagazine(mi, damage, type);
1302 }
1303 }
1304 }
1305
1306 int dummy_version = int.MAX;
1307 PlayerBase parentPlayer = PlayerBase.Cast(src.GetHierarchyRootPlayer());
1308 if (!parentPlayer)
1309 dummy_version -= 1;
1311 src.OnStoreSave(ctx.GetWriteContext());
1312 OnStoreLoad(ctx.GetReadContext(), dummy_version);
1313 return true;
1314 }
1315
1317 override void SetBayonetAttached(bool pState, int slot_idx = -1)
1318 {
1319 m_BayonetAttached = pState;
1320 m_BayonetAttachmentIdx = slot_idx;
1321 }
1322
1323 override bool HasBayonetAttached()
1324 {
1325 return m_BayonetAttached;
1326 }
1327
1329 {
1330 return m_BayonetAttachmentIdx;
1331 }
1332
1333 override void SetButtstockAttached(bool pState, int slot_idx = -1)
1334 {
1335 m_ButtstockAttached = pState;
1336 m_ButtstockAttachmentIdx = slot_idx;
1337 }
1338
1339 override bool HasButtstockAttached()
1340 {
1341 return m_ButtstockAttached;
1342 }
1343
1345 {
1346 return m_ButtstockAttachmentIdx;
1347 }
1348
1349 void HideWeaponBarrel(bool state)
1350 {
1351 if ( !GetGame().IsDedicatedServer() )//hidden for client only
1352 {
1353 ItemOptics optics = GetAttachedOptics();
1354 if ( optics && !optics.AllowsDOF() && m_weaponHideBarrelIdx != -1 )
1355 {
1356 SetSimpleHiddenSelectionState(m_weaponHideBarrelIdx,!state);
1357 }
1358 }
1359 }
1360
1362 {
1363 if (m_magazineSimpleSelectionIndex > -1)
1364 SetSimpleHiddenSelectionState(m_magazineSimpleSelectionIndex,1);
1365 else
1366 SelectionMagazineShow();
1367 }
1368
1370 {
1371 if (m_magazineSimpleSelectionIndex > -1)
1372 SetSimpleHiddenSelectionState(m_magazineSimpleSelectionIndex,0);
1373 else
1374 SelectionMagazineHide();
1375 }
1376
1377 override EntityAI ProcessMeleeItemDamage(int mode = 0)
1378 {
1379 EntityAI attachment;
1380
1381 switch (mode)
1382 {
1383 case 0:
1384 super.ProcessMeleeItemDamage();
1385 break;
1386
1387 case 1:
1388 attachment = GetInventory().FindAttachment(m_ButtstockAttachmentIdx);
1389 break;
1390
1391 case 2:
1392 attachment = GetInventory().FindAttachment(m_BayonetAttachmentIdx);
1393 break;
1394
1395 default:
1396 super.ProcessMeleeItemDamage();
1397 break;
1398 }
1399
1400 if (attachment)
1401 {
1402 attachment.ProcessMeleeItemDamage();
1403 return attachment;
1404 }
1405
1406 return this;
1407 }
1408
1410 {
1411 return true;
1412 }
1413
1415 {
1416 return m_BurstCount;
1417 }
1418
1420 {
1421 m_BurstCount = 0;
1422 }
1423
1424 override void SetActions()
1425 {
1426 super.SetActions();
1433
1436 }
1437
1438 //Debug menu Spawn Ground Special
1439 override void OnDebugSpawn()
1440 {
1441 SpawnAmmo("", SAMF_DEFAULT);
1442 }
1443};
1444
const int INPUT_UDT_WEAPON_REMOTE_EVENT
Definition _constants.c:12
eBleedingSourceType GetType()
void wpnDebugPrint(string s)
Definition Debug.c:9
protected bool IsDamageDestroyed(ActionTarget target)
Definition ActionBase.c:912
void AddAction(typename actionName)
const int ECE_PLACE_ON_SURFACE
void Synchronize()
override bool IsJammed()
Definition Crossbow.c:22
DayZGame g_Game
Definition DayZGame.c:3654
PhxInteractionLayers
Definition DayZPhysics.c:2
WeaponEventID
identifier for events. mainly for rpc purposes
Definition Events.c:6
ProcessEventResult
Definition FSMBase.c:33
FirearmActionLoadBullet FirearmActionBase FirearmActionLoadBulletQuick()
void fsmDebugSpam(string s)
Definition HFSMBase.c:5
InventoryLocationType
types of Inventory Location
void IncreaseOverheating(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Definition ItemBase.c:5119
string Type
bool OnStoreLoad(ParamsReadContext ctx, int version)
override string GetDebugName()
Gets the debug name for the ParticleManager.
PistolAnimState
Definition Pistol_Base.c:3
class JsonUndergroundAreaTriggerData GetPosition
@ AMMO_CHAMBER_RNG
Fully randomizes the ammo type instead of picking one random for all chambers (needs to have type as ...
Definition Weapon_Base.c:26
@ CHAMBER
Chambers bullets.
Definition Weapon_Base.c:16
@ CHAMBER_RNG_SPORADIC
Maybe chambers bullets (full random) example: 0 1 0 0 1 1.
Definition Weapon_Base.c:20
@ MAX_CAPACITY_MAG
Instead of randomizing when type is empty, it looks for the one which has the highest capacity.
Definition Weapon_Base.c:28
@ QUANTITY_RNG
Randomizes the quantity of the bullets in the spawned magazine.
Definition Weapon_Base.c:22
@ CHAMBER_RNG
Maybe chambers bullets (sequential rng) example: 1 1 1 0 0 0.
Definition Weapon_Base.c:18
@ NONE
Attached magazine will be full and no round will be chambered.
Definition Weapon_Base.c:14
@ AMMO_MAG_RNG
Fully randomizes the ammo type instead of picking one random for the entire mag (needs to have type a...
Definition Weapon_Base.c:24
enum FSMTransition WeaponTransition
MuzzleState
override bool IsIdle()
bool IsChamberFiredOut(int idx)
bool IsChamberFull(int idx)
pair ( action, actionType )
Definition Weapon_Base.c:5
int m_actionType
corresponds to Human::actions == RELOAD, MECHANISM, ...
Definition Weapon_Base.c:7
void AbilityRecord(int a, int at)
corresponds to Human::actionTypes == CHAMBERING_ONEBULLET_CLOSED, MECHANISM_CLOSED....
Definition Weapon_Base.c:8
static bool MagazineTypeToAmmoType(string magazineType, out string ammoType)
Helper method.
Definition AmmoTypes.c:12
ammo pile base
static float GetAmmoWeightByBulletType(string bulletType)
proto native vector GetCurrentCameraDirection()
proto native void ConfigGetFloatArray(string path, out TFloatArray values)
Get array of floats from config on path.
override ScriptCallQueue GetCallQueue(int call_category)
Definition DayZGame.c:1153
static proto bool RayCastBullet(vector begPos, vector endPos, PhxInteractionLayers layerMask, Object ignoreObj, out Object hitObject, out vector hitPosition, out vector hitNormal, out float hitFraction)
Wrapper class for managing sound through SEffectManager.
Definition EffectSound.c:5
override void SetAutodestroy(bool auto_destroy)
Sets whether Effect automatically cleans up when it stops.
represents transition src -— event[guard]/action -—|> dst
proto native void SetMeleeBlock(bool pBlock)
this enables/disables block
InventoryLocation.
proto native int GetType()
returns type of InventoryLocation
proto native EntityAI GetParent()
returns parent of current inventory location
static bool IsWeaponLogEnable()
Definition Debug.c:640
Definition EnMath.c:7
Manager class for managing Effect (EffectParticle, EffectSound)
static EffectSound PlaySound(string sound_set, vector position, float play_fade_in=0, float stop_fade_out=0, bool loop=false)
Create and play an EffectSound.
proto void Call(func fn, void param1=NULL, void param2=NULL, void param3=NULL, void param4=NULL, void param5=NULL, void param6=NULL, void param7=NULL, void param8=NULL, void param9=NULL)
adds call into the queue with given parameters and arguments (arguments are held in memory until the ...
proto native ParamsReadContext GetReadContext()
proto native ParamsWriteContext GetWriteContext()
Serialization general interface. Serializer API works with:
Definition Serializer.c:56
proto bool Write(void value_out)
proto bool Read(void value_in)
override void AssembleGun()
Definition Magnum.c:181
override void InitStateMachine()
Definition Magnum.c:88
override void ShowBullet(int muzzleIndex)
Definition Magnum.c:306
override void HideBullet(int muzzleIndex)
Definition Magnum.c:329
signalize mechanism manipulation
Definition Events.c:35
Magazine m_magazine
Definition Events.c:38
WeaponEventID GetEventID()
returns id from enum WeaponEventID
Definition Events.c:42
void WriteToContext(ParamsWriteContext ctx)
Definition Events.c:54
DayZPlayer m_player
Definition Events.c:37
weapon finite state machine
script counterpart to engine's class Weapon
bool ProcessWeaponEvent(WeaponEventBase e)
weapon's fsm handling of events @NOTE: warning: ProcessWeaponEvent can be called only within DayZPlay...
protected ref PropertyModifiers m_PropertyModifierObject
Definition Weapon_Base.c:64
protected int m_BayonetAttachmentIdx
Definition Weapon_Base.c:53
override void OnDebugSpawn()
void ResetWeaponAnimState()
protected bool m_BayonetAttached
Definition Weapon_Base.c:50
void InitStateMachine()
bool InitDOFProperties(out array< float > temp_array)
Initializes DOF properties for weapon's ironsight/optics cameras.
override void OnItemLocationChanged(EntityAI old_owner, EntityAI new_owner)
protected float m_WeaponLength
Definition Weapon_Base.c:59
void ResetBurstCount()
int GetAbilityCount()
override void OnInventoryExit(Man player)
void SetWeaponAnimState(int state)
bool CanEnterIronsights()
protected int m_ButtstockAttachmentIdx
Definition Weapon_Base.c:54
Magazine SpawnAttachedMagazine(string magazineType="", int flags=WeaponWithAmmoFlags.CHAMBER)
Try to spawn and attach a magazine.
static Weapon_Base CreateWeaponWithAmmo(string weaponType, string magazineType="", int flags=WeaponWithAmmoFlags.CHAMBER)
Create weapon with ammo.
bool IsRemoteWeapon()
bool CanEjectBullet()
bool JamCheck(int muzzleIndex)
override int GetBayonetAttachmentIdx()
void SaveCurrentFSMState(ParamsWriteContext ctx)
void ShowBullet(int muzzleIndex)
bool ProcessWeaponAbortEvent(WeaponEventBase e)
bool InitReliability(out array< float > reliability_array)
override void OnStoreSave(ParamsWriteContext ctx)
int GetCurrentStableStateID()
tries to return identifier of current stable state (or nearest stable state if unstable state is curr...
void Weapon_Base()
Definition Weapon_Base.c:67
float GetChanceToJam()
override protected float GetWeightSpecialized(bool forceRecalc=false)
RecoilBase SpawnRecoilObject()
bool IsIdle()
override bool HasButtstockAttached()
WeaponStateBase GetCurrentState()
returns currently active state
bool IsShowingChamberedBullet()
bool LiftWeaponCheck(PlayerBase player)
void EEFired(int muzzleType, int mode, string ammoType)
bool CanFire()
bool EjectCartridge(int muzzleIndex, out float ammoDamage, out string ammoTypeName)
unload bullet from chamber or internal magazine
bool InitWeaponLength()
gets weapon length from config for weaponlift raycast
bool IsWaitingForActionFinish()
returns true if state machine started playing action/actionType and waits for finish
override void EEInit()
void SyncEventToRemote(WeaponEventBase e)
ref array< float > GetWeaponDOF()
protected ref WeaponFSM m_fsm
weapon abilities
Definition Weapon_Base.c:47
void HideBullet(int muzzleIndex)
protected bool m_ButtstockAttached
Definition Weapon_Base.c:51
void SetSyncJammingChance(float jamming_chance)
void OnFireModeChange(int fireMode)
bool LoadCurrentFSMState(ParamsReadContext ctx, int version)
bool CanChamberBullet(int muzzleIndex, Magazine mag)
override bool CanReleaseAttachment(EntityAI attachment)
void HideWeaponBarrel(bool state)
int GetBurstCount()
void SyncSelectionState(bool has_bullet, bool has_mag)
void RandomizeFSMState()
With the parameters given, selects a random suitable state for the FSM of the weapon @WARNING: Weapon...
protected array< MuzzleState > GetMuzzleStates()
Helper method for RandomizeFSMState.
bool FillInnerMagazine(string ammoType="", int flags=WeaponWithAmmoFlags.CHAMBER)
Try to fill the inner magazine.
override void EEItemDetached(EntityAI item, string slot_name)
int GetInternalStateID()
override int GetSlotsCountCorrect()
Returns number of slots for attachments corrected for weapons.
void ShowMagazine()
ref array< float > m_DOFProperties
Definition Weapon_Base.c:61
override void AfterStoreLoad()
int GetWeaponAnimState()
float GetSyncChanceToJam()
override void SetButtstockAttached(bool pState, int slot_idx=-1)
override void SetBayonetAttached(bool pState, int slot_idx=-1)
attachment helpers (firearm melee)
override void EEItemLocationChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
void OnFire(int muzzle_index)
bool CopyWeaponStateFrom(notnull Weapon_Base src)
override bool OnStoreLoad(ParamsReadContext ctx, int version)
PropertyModifiers GetPropertyModifierObject()
bool HasActionAbility(int action, int actionType)
query if weapon supports action and actionType
override EntityAI ProcessMeleeItemDamage(int mode=0)
override void EEItemAttached(EntityAI item, string slot_name)
bool CanProcessAction(int action, int actionType)
override bool HasBayonetAttached()
AbilityRecord GetAbility(int index)
override void OnInventoryEnter(Man player)
void AssembleGun()
override on weapons with some assembly required
bool SpawnAmmo(string magazineType="", int flags=WeaponWithAmmoFlags.CHAMBER)
General method trying to attch magazine, fill inner magazine and fill chamber.
void SetInitialState(WeaponStableState initState)
protected int m_BurstCount
Definition Weapon_Base.c:52
bool CanProcessWeaponEvents()
void ForceSyncSelectionState()
bool FillChamber(string ammoType="", int flags=WeaponWithAmmoFlags.CHAMBER)
Try to fill the chamber.
bool IsJammed()
override int GetButtstockAttachmentIdx()
void ValidateAndRepair()
void SetJammed(bool value)
override bool CanRemoveFromHands(EntityAI parent)
void HideMagazine()
int GetWeaponSpecificCommand(int weaponAction, int subCommand)
override void SetActions()
represents weapon's stable state (i.e. the basic states that the weapon will spend the most time in)
Definition Crossbow.c:27
override bool HasBullet()
Definition Crossbow.c:31
override bool HasMagazine()
Definition Crossbow.c:32
represent weapon state base
Definition BulletHide.c:2
void SetCalcDetails(string details)
Definition Debug.c:728
void AddCalcDetails(string details)
Definition Debug.c:734
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
proto string ToString()
static const vector Zero
Definition EnConvert.c:110
DayZPlayerInstanceType
defined in C++
proto native CGame GetGame()
void Error(string err)
Messagebox with error message.
Definition EnDebug.c:90
proto void Print(void var)
Prints content of variable to console/log.
enum ShapeType ErrorEx
array< string > TStringArray
Definition EnScript.c:685
static int RandomIntInclusive(int min, int max)
Returns a random int number between and min [inclusive] and max [inclusive].
Definition EnMath.c:53
const int CALL_CATEGORY_GAMEPLAY
Definition tools.c:10