DayZ 1.30
DayZ Explorer by KGB
 
Загрузка...
Поиск...
Не найдено
ItemBase.c
См. документацию.
1class DummyItem extends ItemBase
2{
3 override bool CanPutAsAttachment(EntityAI parent)
4 {
5 return true;
6 }
7};
8
10{
13
14 void ItemSoundEvent(int soundId, int slotId)
15 {
16 m_SoundId = soundId;
17 m_SlotId = slotId;
18 }
19}
20
21//const bool QUANTITY_DEBUG_REMOVE_ME = false;
22
23class ItemBase extends InventoryItem
24{
27
29
32 // ============================================
33 // Variable Manipulation System
34 // ============================================
35 // Quantity
36
39
40 float m_StoreLoadedQuantity = float.LOWEST;
41 // Wet
42 float m_VarWet;
43 float m_VarWetPrev;//for client to know wetness changed during synchronization
44
45 // Cleanness
47 // impact sounds
52 //
61 bool m_FixDamageSystemInit = false; //can be changed on storage version check
62 bool can_this_be_combined; //Check if item can be combined
63 bool m_CanThisBeSplit; //Check if item can be split
64 bool m_IsStoreLoad = false;
65 protected bool m_IsResultOfSplit
66
68 // items color variables
73 //-------------------------------------------------------
74
75 // light source managing
77
81
82 //==============================================
83 // agent system
84 private int m_AttachedAgents;
85
88
89
90 // Weapons & suppressors particle effects
96
97 // Overheating effects
101 int m_ShotsToStartOverheating = 0; // After these many shots, the overheating effect begins
102 int m_MaxOverheatingValue = 0; // Limits the number of shots that will be tracked
103 float m_OverheatingDecayInterval = 1; // Timer's interval for decrementing overheat effect's lifespan
104 ref array <ref OverheatingParticle> m_OverheatingParticles;
105
106 // Admin Log
107 PluginAdminLog m_AdminLog;
108
109 // misc
111
112 // Attachment Locking variables
114
115 // ItemSoundHandler variables
116 protected const int ITEM_SOUNDS_MAX = 63; // optimize network synch
117 protected int m_SoundSyncPlay; // deprecated but left here for legacy modding compatibility
118 protected int m_SoundSyncStop; // deprecated but left here for legacy modding compatibility
119 protected int m_SoundSyncSlotID = InventorySlots.INVALID; // deprecated but left here for legacy modding compatibility
120
121 protected ref array<ref ItemSoundEvent> m_SoundEventQueue; // server-side dynamic sound queue
123
124 // -------------------------------------------------------------------------
125 void ItemBase()
126 {
127 SetEventMask(EntityEvent.INIT); // Enable EOnInit event
131
132 if (!g_Game.IsHeadlessOrDedicatedServer())
133 {
134 if (HasMuzzle())
135 {
137
139 {
141 }
142 }
143
145 m_ActionsInitialize = false;
146 }
147
148 m_OldLocation = null;
149
150 if (g_Game.IsServer())
151 {
152 m_AdminLog = PluginAdminLog.Cast(GetPlugin(PluginAdminLog));
153 }
154
155 m_IsResultOfSplit = false;
156 }
157
158 override void InitItemVariables()
159 {
160 super.InitItemVariables();
161
162 ItemBaseType itemBaseType = ItemBaseType.Cast(GetEntityType());
163
164 m_VarQuantity = itemBaseType.m_VarQuantityInit; //should be by the CE, this is just a precaution
165 m_VarWet = itemBaseType.m_VarWetInit;
166 m_Cleanness = itemBaseType.m_CleannessInit;
167
168 m_WantPlayImpactSound = false;
169 m_ImpactSpeed = 0.0;
170
171 // TODO: move to EntityType (ONLY IF POSSIBLE, GetQuantity() plays against it)
172 //{
173 if (IsLiquidContainer() && GetQuantity() != 0)
175 //}
176
177 m_IsBeingPlaced = false;
178 m_IsHologram = false;
179 m_IsTakeable = true;
180 m_CanBeMovedOverride = false;
181
182 //Define if item can be split and set ability to be combined accordingly
183 can_this_be_combined = ItemBaseType.Cast(GetEntityType()).m_CanBeSplit;
185
186 //RegisterNetSyncVariableInt("m_VariablesMask");
187 if (HasQuantity())
188 RegisterNetSyncVariableFloat("m_VarQuantity", itemBaseType.m_VarQuantityMin, itemBaseType.m_VarQuantityMax);
189
190 RegisterNetSyncVariableFloat("m_VarWet", GetWetMin(), GetWetMax(), 2);
191 RegisterNetSyncVariableInt("m_VarLiquidType");
192 RegisterNetSyncVariableInt("m_Cleanness",0,1);
193
194 RegisterNetSyncVariableBoolSignal("m_WantPlayImpactSound");
195 RegisterNetSyncVariableFloat("m_ImpactSpeed");
196 RegisterNetSyncVariableInt("m_ImpactSoundSurfaceHash");
197
198 RegisterNetSyncVariableInt("m_ColorComponentR", 0, 255);
199 RegisterNetSyncVariableInt("m_ColorComponentG", 0, 255);
200 RegisterNetSyncVariableInt("m_ColorComponentB", 0, 255);
201 RegisterNetSyncVariableInt("m_ColorComponentA", 0, 255);
202
203 RegisterNetSyncVariableBool("m_IsBeingPlaced");
204 RegisterNetSyncVariableBool("m_IsTakeable");
205 RegisterNetSyncVariableBool("m_IsHologram");
206
209 {
210 RegisterNetSyncVariableInt("m_SoundSyncPlay", 0, ITEM_SOUNDS_MAX);
211 RegisterNetSyncVariableInt("m_SoundSyncStop", 0, ITEM_SOUNDS_MAX);
212 RegisterNetSyncVariableInt("m_SoundSyncSlotID", int.MIN, int.MAX);
213 }
214
216 }
217
218 override int GetQuickBarBonus()
219 {
220 return ItemBaseType.Cast(GetEntityType()).m_QuickBarBonus;
221 }
222
224 {
226 if (!m_InputActionMap)
227 {
229 m_InputActionMap = iam;
230 SetActions();
231 m_ItemTypeActionsMap.Insert(this.Type(), m_InputActionMap);
232 }
233 }
234
235 override void GetActions(typename action_input_type, out array<ActionBase_Basic> actions)
236 {
238 {
239 m_ActionsInitialize = true;
241 }
242
243 actions = m_InputActionMap.Get(action_input_type);
244 }
245
254
255 void AddAction(typename actionName)
256 {
257 ActionBase action = ActionManagerBase.GetAction(actionName);
258
259 if (!action)
260 {
261 Debug.LogError("Action " + actionName + " dosn't exist!");
262 return;
263 }
264
265 typename ai = action.GetInputType();
266 if (!ai)
267 {
268 m_ActionsInitialize = false;
269 return;
270 }
271
272 array<ActionBase_Basic> action_array = m_InputActionMap.Get(ai);
273 if (!action_array)
274 {
275 action_array = new array<ActionBase_Basic>;
276 m_InputActionMap.Insert(ai, action_array);
277 }
278#ifdef ENABLE_LOGGING
280 {
281 Debug.ActionLog(action.ToString() + " -> " + ai, this.ToString() , "n/a", "Add action");
282 }
283#endif
284
285 if (action_array.Find(action) != -1)
286 {
287 Debug.Log("Action " + action.Type() + " already added to " + this + ", skipping!");
288 }
289 else
290 {
291 action_array.Insert(action);
292 }
293 }
294
295 void RemoveAction(typename actionName)
296 {
297 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
298 ActionBase action = player.GetActionManager().GetAction(actionName);
299 typename ai = action.GetInputType();
300 array<ActionBase_Basic> action_array = m_InputActionMap.Get(ai);
301
302 if (action_array)
303 {
304 action_array.RemoveItem(action);
305 }
306 }
307
309
311
312 // Loads muzzle flash particle configuration from config and saves it to a map for faster access
314 {
315 if (!m_OnFireEffect)
317
320
321 string config_to_search = "CfgVehicles";
322 string muzzle_owner_config;
323
324 if (!m_OnFireEffect.Contains(id))
325 {
326 if (IsInherited(Weapon))
327 config_to_search = "CfgWeapons";
328
329 muzzle_owner_config = config_to_search + " " + GetType() + " ";
330
331 string config_OnFire_class = muzzle_owner_config + "Particles " + "OnFire ";
332
333 int config_OnFire_subclass_count = g_Game.ConfigGetChildrenCount(config_OnFire_class);
334
335 if (config_OnFire_subclass_count > 0)
336 {
338
339 for (int i = 0; i < config_OnFire_subclass_count; i++)
340 {
341 string particle_class = "";
342 g_Game.ConfigGetChildName(config_OnFire_class, i, particle_class);
343 string config_OnFire_entry = config_OnFire_class + particle_class;
344 WeaponParticlesOnFire WPOF = new WeaponParticlesOnFire(this, config_OnFire_entry);
345 WPOF_array.Insert(WPOF);
346 }
347
348
349 m_OnFireEffect.Insert(id, WPOF_array);
350 }
351 }
352
353 if (!m_OnBulletCasingEjectEffect.Contains(id))
354 {
355 config_to_search = "CfgWeapons"; // Bullet Eject efect is supported on weapons only.
356 muzzle_owner_config = config_to_search + " " + GetType() + " ";
357
358 string config_OnBulletCasingEject_class = muzzle_owner_config + "Particles " + "OnBulletCasingEject ";
359
360 int config_OnBulletCasingEject_count = g_Game.ConfigGetChildrenCount(config_OnBulletCasingEject_class);
361
362 if (config_OnBulletCasingEject_count > 0 && IsInherited(Weapon))
363 {
365
366 for (i = 0; i < config_OnBulletCasingEject_count; i++)
367 {
368 string particle_class2 = "";
369 g_Game.ConfigGetChildName(config_OnBulletCasingEject_class, i, particle_class2);
370 string config_OnBulletCasingEject_entry = config_OnBulletCasingEject_class + particle_class2;
371 WeaponParticlesOnBulletCasingEject WPOBE = new WeaponParticlesOnBulletCasingEject(this, config_OnBulletCasingEject_entry);
372 WPOBE_array.Insert(WPOBE);
373 }
374
375
376 m_OnBulletCasingEjectEffect.Insert(id, WPOBE_array);
377 }
378 }
379 }
380
381 // Loads muzzle flash particle configuration from config and saves it to a map for faster access
383 {
386
387 if (!m_OnOverheatingEffect.Contains(id))
388 {
389 string config_to_search = "CfgVehicles";
390
391 if (IsInherited(Weapon))
392 config_to_search = "CfgWeapons";
393
394 string muzzle_owner_config = config_to_search + " " + GetType() + " ";
395 string config_OnOverheating_class = muzzle_owner_config + "Particles " + "OnOverheating ";
396
397 if (g_Game.ConfigIsExisting(config_OnOverheating_class))
398 {
399
400 m_ShotsToStartOverheating = g_Game.ConfigGetFloat(config_OnOverheating_class + "shotsToStartOverheating");
401
403 {
404 m_ShotsToStartOverheating = -1; // This prevents futher readings from config for future creations of this item
405 string error = "Error reading config " + GetType() + ">Particles>OnOverheating - Parameter shotsToStartOverheating is configured wrong or is missing! Its value must be 1 or higher!";
406 Error(error);
407 return;
408 }
409
410 m_OverheatingDecayInterval = g_Game.ConfigGetFloat(config_OnOverheating_class + "overheatingDecayInterval");
411 m_MaxOverheatingValue = g_Game.ConfigGetFloat(config_OnOverheating_class + "maxOverheatingValue");
412
413
414
415 int config_OnOverheating_subclass_count = g_Game.ConfigGetChildrenCount(config_OnOverheating_class);
417
418 for (int i = 0; i < config_OnOverheating_subclass_count; i++)
419 {
420 string particle_class = "";
421 g_Game.ConfigGetChildName(config_OnOverheating_class, i, particle_class);
422 string config_OnOverheating_entry = config_OnOverheating_class + particle_class;
423 int entry_type = g_Game.ConfigGetType(config_OnOverheating_entry);
424
425 if (entry_type == CT_CLASS)
426 {
427 WeaponParticlesOnOverheating WPOF = new WeaponParticlesOnOverheating(this, config_OnOverheating_entry);
428 WPOOH_array.Insert(WPOF);
429 }
430 }
431
432
433 m_OnOverheatingEffect.Insert(id, WPOOH_array);
434 }
435 }
436 }
437
439 {
440 return m_OverheatingShots;
441 }
442
443 void IncreaseOverheating(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
444 {
445 if (m_MaxOverheatingValue > 0)
446 {
448
451
452 m_CheckOverheating.Stop();
453 m_CheckOverheating.Run(m_OverheatingDecayInterval, this, "OnOverheatingDecay");
454
455 CheckOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
456 }
457 }
458
459 void CheckOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
460 {
462 UpdateOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
463
465 StartOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
466
468 StopOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
469
471 {
473 }
474 }
475
480
482 {
483 if (m_MaxOverheatingValue > 0)
484 m_OverheatingShots -= 1 + m_OverheatingShots / m_MaxOverheatingValue; // The hotter a barrel is, the faster it needs to cool down.
485 else
487
488 if (m_OverheatingShots <= 0)
489 {
490 m_CheckOverheating.Stop();
492 }
493 else
494 {
497
498 m_CheckOverheating.Stop();
499 m_CheckOverheating.Run(m_OverheatingDecayInterval, this, "OnOverheatingDecay");
500 }
501
502 CheckOverheating(this, "", this);
503 }
504
505 void StartOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
506 {
508 ItemBase.PlayOverheatingParticles(this, ammoType, this, suppressor, "CfgWeapons");
509 }
510
511 void UpdateOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
512 {
514 ItemBase.UpdateOverheatingParticles(this, ammoType, this, suppressor, "CfgWeapons");
516 }
517
518 void StopOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
519 {
521 ItemBase.StopOverheatingParticles(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
522 }
523
524 void RegisterOverheatingParticle(Particle p, float min_heat_coef, float max_heat_coef, int particle_id, Object parent, vector local_pos, vector local_ori)
525 {
528
530 OP.RegisterParticle(p);
531 OP.SetOverheatingLimitMin(min_heat_coef);
532 OP.SetOverheatingLimitMax(max_heat_coef);
533 OP.SetParticleParams(particle_id, parent, local_pos, local_ori);
534
535 m_OverheatingParticles.Insert(OP);
536 }
537
539 {
540 if (m_MaxOverheatingValue > 0)
542
543 return -1;
544 }
545
547 {
549 {
550 float overheat_coef = GetOverheatingCoef();
551 int count = m_OverheatingParticles.Count();
552
553 for (int i = count; i > 0; --i)
554 {
555 int id = i - 1;
557 Particle p = OP.GetParticle();
558
559 float overheat_min = OP.GetOverheatingLimitMin();
560 float overheat_max = OP.GetOverheatingLimitMax();
561
562 if (overheat_coef < overheat_min && overheat_coef >= overheat_max)
563 {
564 if (p)
565 {
566 p.Stop();
567 OP.RegisterParticle(null);
568 }
569 }
570 }
571 }
572 }
573
575 {
577 {
578 for (int i = m_OverheatingParticles.Count(); i > 0; i--)
579 {
580 int id = i - 1;
582
583 if (OP)
584 {
585 Particle p = OP.GetParticle();
586
587 if (p)
588 {
589 p.Stop();
590 }
591
592 delete OP;
593 }
594 }
595
598 }
599 }
600
602 float GetInfectionChance(int system = 0, Param param = null)
603 {
604 return 0.0;
605 }
606
607
608 float GetDisinfectQuantity(int system = 0, Param param1 = null)
609 {
610 return 250;//default value
611 }
612
614 {
615 return 0;
616 }
617
620 {
621 if (IsInherited(Weapon) || IsInherited(SuppressorBase))
622 return true;
623
624 return false;
625 }
626
629 {
630 if (!m_WeaponTypeToID)
632
633 if (m_WeaponTypeToID.Contains(GetType()))
634 {
635 return m_WeaponTypeToID.Get(GetType());
636 }
637 else
638 {
639 // Register new weapon ID
641 }
642
644 }
645
652 {
653 return -1;
654 }
655
656
657
658 // -------------------------------------------------------------------------
660 {
661 if (g_Game && g_Game.GetPlayer() && (!g_Game.IsDedicatedServer()))
662 {
663 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
664 int r_index = player.GetHumanInventory().FindUserReservedLocationIndex(this);
665
666 if (r_index >= 0)
667 {
669 player.GetHumanInventory().GetUserReservedLocation(r_index,r_il);
670
671 player.GetHumanInventory().ClearUserReservedLocationAtIndex(r_index);
672 int r_type = r_il.GetType();
673 if (r_type == InventoryLocationType.CARGO || r_type == InventoryLocationType.PROXYCARGO)
674 {
675 r_il.GetParent().GetOnReleaseLock().Invoke(this);
676 }
677 else if (r_type == InventoryLocationType.ATTACHMENT)
678 {
679 r_il.GetParent().GetOnAttachmentReleaseLock().Invoke(this, r_il.GetSlot());
680 }
681
682 }
683
684 player.GetHumanInventory().ClearUserReservedLocation(this);
685 }
686
687 if (m_LockingSound)
689 }
690
691
692
693 // -------------------------------------------------------------------------
695 {
696 return ItemBase.m_DebugActionsMask;
697 }
698
699 static bool HasDebugActionsMask(int mask)
700 {
701 return ItemBase.m_DebugActionsMask & mask;
702 }
703
704 static void SetDebugActionsMask(int mask)
705 {
706 ItemBase.m_DebugActionsMask = mask;
707 }
708
709 static void AddDebugActionsMask(int mask)
710 {
711 ItemBase.m_DebugActionsMask |= mask;
712 }
713
714 static void RemoveDebugActionsMask(int mask)
715 {
716 ItemBase.m_DebugActionsMask &= ~mask;
717 }
718
719 static void ToggleDebugActionsMask(int mask)
720 {
721 if (HasDebugActionsMask(mask))
722 {
724 }
725 else
726 {
728 }
729 }
730
731 // -------------------------------------------------------------------------
733 {
734 if (GetEconomyProfile())
735 {
736 float q_max = GetEconomyProfile().GetQuantityMax();
737 if (q_max > 0)
738 {
739 float q_min = GetEconomyProfile().GetQuantityMin();
740 float quantity_randomized = Math.RandomFloatInclusive(q_min, q_max);
741
742 if (HasComponent(COMP_TYPE_ENERGY_MANAGER))//more direct access for speed
743 {
744 ComponentEnergyManager comp = GetCompEM();
745 if (comp && (comp.GetEnergyMaxPristine() || comp.GetEnergyAtSpawn()))//checking for a potential for energy, we need to check both values, as both are optional, only when both are set to 0, we know the item can't have energy
746 {
747 comp.SetEnergy0To1(quantity_randomized);
748 }
749 }
750 else if (HasQuantity())
751 {
752 SetQuantityNormalized(quantity_randomized, false);
753 //PrintString("<==> Normalized quantity for item: "+ GetType()+", qmin:"+q_min.ToString()+"; qmax:"+q_max.ToString()+";quantity:" +quantity_randomized.ToString());
754 }
755
756 }
757 }
758 }
759
762 {
763 EntityAI parent = GetHierarchyParent();
764
765 if (parent)
766 {
767 InventoryLocation inventory_location_to_lock = new InventoryLocation;
768 GetInventory().GetCurrentInventoryLocation(inventory_location_to_lock);
769 parent.GetInventory().SetSlotLock(inventory_location_to_lock.GetSlot(), true);
770 }
771 }
772
775 {
776 EntityAI parent = GetHierarchyParent();
777
778 if (parent)
779 {
780 InventoryLocation inventory_location_to_unlock = new InventoryLocation;
781 GetInventory().GetCurrentInventoryLocation(inventory_location_to_unlock);
782 parent.GetInventory().SetSlotLock(inventory_location_to_unlock.GetSlot(), false);
783 }
784 }
785
786 override void CombineItemsClient(EntityAI entity2, bool use_stack_max = true)
787 {
788 /*
789 ref Param1<EntityAI> item = new Param1<EntityAI>(entity2);
790 RPCSingleParam(ERPCs.RPC_ITEM_COMBINE, item, g_Game.GetPlayer());
791 */
792 ItemBase item2 = ItemBase.Cast(entity2);
793
794 if (g_Game.IsClient())
795 {
797 {
800 ctx.Write(-1);
801 ItemBase i1 = this; // @NOTE: workaround for correct serialization
802 ctx.Write(i1);
803 ctx.Write(item2);
804 ctx.Write(use_stack_max);
805 ctx.Write(-1);
806 ctx.Send();
807
808 if (IsCombineAll(item2, use_stack_max))
809 {
810 g_Game.GetPlayer().GetInventory().AddInventoryReservationEx(item2,null,GameInventory.c_InventoryReservationTimeoutShortMS);
811 }
812 }
813 }
814 else if (!g_Game.IsMultiplayer())
815 {
816 CombineItems(item2, use_stack_max);
817 }
818 }
819
821 {
822 return (GetLiquidType() != 0 && HasQuantity());
823 }
824
826 {
827 return ItemBaseType.Cast(GetEntityType()).m_LiquidContainerMask != 0;
828 }
829
831 {
832 return ItemBaseType.Cast(GetEntityType()).m_LiquidContainerMask;
833 }
834
836 {
837 //m_LiquidContainerMask & GROUP_LIQUID_BLOOD ???
838 return false;
839 }
840
841 bool IsNVG()
842 {
843 return false;
844 }
845
847 {
848 return true;
849 }
850
853 override bool IsExplosive()
854 {
855 return false;
856 }
857
859 {
860 return "";
861 }
862
864
866 {
867 return false;
868 }
869
871 {
872 return true;
873 }
874
875 //--- ACTION CONDITIONS
876 //direction
877 override bool IsFacingPlayerEx(DayZPlayer player, string selection)
878 {
879 return IsFacingPlayer(PlayerBase.Cast(player),selection);
880 }
881
883 override bool IsPlayerInsideEx(DayZPlayer player, string selection)
884 {
885 return IsPlayerInside(PlayerBase.Cast(player),selection);;
886 }
887
888 bool IsFacingPlayer(PlayerBase player, string selection)
889 {
890 return true;
891 }
892
893 bool IsPlayerInside(PlayerBase player, string selection)
894 {
895 return true;
896 }
897
898 override bool CanObstruct()
899 {
900 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
901 return !player || !IsPlayerInside(player, "");
902 }
903
904 override bool IsBeingPlaced()
905 {
906 return m_IsBeingPlaced;
907 }
908
909 void SetIsBeingPlaced(bool is_being_placed)
910 {
911 m_IsBeingPlaced = is_being_placed;
912 if (!is_being_placed)
914 SetSynchDirty();
915 }
916
917 //server-side
919
920 override bool IsHologram()
921 {
922 return m_IsHologram;
923 }
924
926 {
927 return ItemBaseType.Cast(GetEntityType()).m_CanBeDigged;
928 }
929
931 {
932 return 1;
933 }
934
936 {
937 return false;
938 }
939
940 void SetIsHologram(bool is_hologram)
941 {
942 m_IsHologram = is_hologram;
943 SetSynchDirty();
944 }
945 /*
946 protected float GetNutritionalEnergy()
947 {
948 Edible_Base edible = Edible_Base.Cast(this);
949 return edible.GetFoodEnergy();
950 }
951
952 protected float GetNutritionalWaterContent()
953 {
954 Edible_Base edible = Edible_Base.Cast(this);
955 return edible.GetFoodWater();
956 }
957
958 protected float GetNutritionalIndex()
959 {
960 Edible_Base edible = Edible_Base.Cast(this);
961 return edible.GetFoodNutritionalIndex();
962 }
963
964 protected float GetNutritionalFullnessIndex()
965 {
966 Edible_Base edible = Edible_Base.Cast(this);
967 return edible.GetFoodTotalVolume();
968 }
969
970 protected float GetNutritionalToxicity()
971 {
972 Edible_Base edible = Edible_Base.Cast(this);
973 return edible.GetFoodToxicity();
974
975 }
976 */
977
978
979 // -------------------------------------------------------------------------
980 override void OnMovedInsideCargo(EntityAI container)
981 {
982 super.OnMovedInsideCargo(container);
983
984 MiscGameplayFunctions.RemoveAllAttachedChildrenByTypename(this, {Bolt_Base});
985 }
986
987 override void EEItemLocationChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
988 {
989 super.EEItemLocationChanged(oldLoc, newLoc);
990
991 PlayerBase newPlayer = null;
992 PlayerBase oldPlayer = null;
993
994 if (newLoc.GetParent())
995 newPlayer = PlayerBase.Cast(newLoc.GetParent().GetHierarchyRootPlayer());
996
997 if (oldLoc.GetParent())
998 oldPlayer = PlayerBase.Cast(oldLoc.GetParent().GetHierarchyRootPlayer());
999
1000 if (oldPlayer && oldLoc.GetType() == InventoryLocationType.HANDS)
1001 {
1002 int rIndex = oldPlayer.GetHumanInventory().FindUserReservedLocationIndex(this);
1003
1004 if (rIndex >= 0)
1005 {
1007 oldPlayer.GetHumanInventory().GetUserReservedLocation(rIndex, rIl);
1008
1009 oldPlayer.GetHumanInventory().ClearUserReservedLocationAtIndex(rIndex);
1010 int rType = rIl.GetType();
1011 if (rType == InventoryLocationType.CARGO || rType == InventoryLocationType.PROXYCARGO)
1012 {
1013 rIl.GetParent().GetOnReleaseLock().Invoke(this);
1014 }
1015 else if (rType == InventoryLocationType.ATTACHMENT)
1016 {
1017 rIl.GetParent().GetOnAttachmentReleaseLock().Invoke(this, rIl.GetSlot());
1018 }
1019
1020 }
1021 }
1022
1023 if (newLoc.GetType() == InventoryLocationType.HANDS && oldLoc.GetType() != InventoryLocationType.TEMP)
1024 {
1025 if (newPlayer)
1026 newPlayer.ForceStandUpForHeavyItems(newLoc.GetItem());
1027
1028 if (newPlayer == oldPlayer)
1029 {
1030 if (oldLoc.GetParent() && newPlayer.GetHumanInventory().LocationGetEntity(oldLoc) == NULL)
1031 {
1032 if (oldLoc.GetType() == InventoryLocationType.CARGO)
1033 {
1034 if (oldLoc.GetParent().GetInventory().TestAddEntityInCargoExLoc(oldLoc, false, false, false, true, false, false))
1035 {
1036 newPlayer.GetHumanInventory().SetUserReservedLocation(this,oldLoc);
1037 }
1038 }
1039 else
1040 {
1041 newPlayer.GetHumanInventory().SetUserReservedLocation(this,oldLoc);
1042 }
1043 }
1044
1045 if (newPlayer.GetHumanInventory().FindUserReservedLocationIndex(this) >= 0)
1046 {
1047 int type = oldLoc.GetType();
1048 if (type == InventoryLocationType.CARGO || type == InventoryLocationType.PROXYCARGO)
1049 {
1050 oldLoc.GetParent().GetOnSetLock().Invoke(this);
1051 }
1052 else if (type == InventoryLocationType.ATTACHMENT)
1053 {
1054 oldLoc.GetParent().GetOnAttachmentSetLock().Invoke(this, oldLoc.GetSlot());
1055 }
1056 }
1057 if (!m_OldLocation)
1058 {
1059 m_OldLocation = new InventoryLocation;
1060 }
1061 m_OldLocation.Copy(oldLoc);
1062 }
1063 else
1064 {
1065 if (m_OldLocation)
1066 {
1067 m_OldLocation.Reset();
1068 }
1069 }
1070
1071 g_Game.GetAnalyticsClient().OnItemAttachedAtPlayer(this,"Hands");
1072 }
1073 else
1074 {
1075 if (newPlayer)
1076 {
1077 int resIndex = newPlayer.GetHumanInventory().FindCollidingUserReservedLocationIndex(this, newLoc);
1078 if (resIndex >= 0)
1079 {
1081 newPlayer.GetHumanInventory().GetUserReservedLocation(resIndex, il);
1082 ItemBase it = ItemBase.Cast(il.GetItem());
1083 newPlayer.GetHumanInventory().ClearUserReservedLocationAtIndex(resIndex);
1084 int rel_type = il.GetType();
1085 if (rel_type == InventoryLocationType.CARGO || rel_type == InventoryLocationType.PROXYCARGO)
1086 {
1087 il.GetParent().GetOnReleaseLock().Invoke(it);
1088 }
1089 else if (rel_type == InventoryLocationType.ATTACHMENT)
1090 {
1091 il.GetParent().GetOnAttachmentReleaseLock().Invoke(it, il.GetSlot());
1092 }
1093 //it.GetOnReleaseLock().Invoke(it);
1094 }
1095 }
1096 else if (oldPlayer && newLoc.GetType() == InventoryLocationType.GROUND && m_ThrowItemOnDrop)
1097 {
1098 //ThrowPhysically(oldPlayer, vector.Zero);
1099 m_ThrowItemOnDrop = false;
1100 }
1101
1102 if (m_OldLocation)
1103 {
1104 m_OldLocation.Reset();
1105 }
1106 }
1107
1108 if (oldLoc.GetType() == InventoryLocationType.TEMP)
1109 {
1110 PluginInventoryRepair.Cast(GetPlugin(PluginInventoryRepair)).Remove(oldLoc.GetItem());
1111 }
1112
1113 if (newLoc.GetType() == InventoryLocationType.TEMP)
1114 {
1115 PluginInventoryRepair.Cast(GetPlugin(PluginInventoryRepair)).Add(oldLoc.GetItem());
1116 }
1117 }
1118
1119 override void EOnContact(IEntity other, Contact extra)
1120 {
1122 {
1123 int liquidType = -1;
1124 ItemBaseType itemBaseType = ItemBaseType.Cast(GetEntityType());
1125 float impactSpeed = ProcessImpactSoundEx(other, extra, itemBaseType.m_ConfigWeight, m_ImpactSoundSurfaceHash, liquidType);
1126 if (impactSpeed > 0.0)
1127 {
1128 m_ImpactSpeed = impactSpeed;
1129 #ifndef SERVER
1130 #ifndef NO_GUI
1131 PlayImpactSound(itemBaseType.m_ConfigWeight, m_ImpactSpeed, m_ImpactSoundSurfaceHash);
1132 #endif
1133 #else
1134 m_WantPlayImpactSound = true;
1135 SetSynchDirty();
1136 #endif
1137 m_CanPlayImpactSound = (liquidType == -1);// prevents further playing of the sound when the surface is a liquid type
1138 }
1139 }
1140
1141 #ifdef SERVER
1142 if (GetCompEM() && GetCompEM().IsPlugged())
1143 {
1144 if (GetCompEM().GetCordLength() < vector.Distance(GetPosition(), GetCompEM().GetEnergySource().GetPosition()))
1145 GetCompEM().UnplugThis();
1146 }
1147 #endif
1148 }
1149
1151
1152 override void OnCreatePhysics()
1153 {
1155 }
1156
1157 override void OnItemAttachmentSlotChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
1158 {
1159
1160 }
1161 // -------------------------------------------------------------------------
1162 override void OnItemLocationChanged(EntityAI old_owner, EntityAI new_owner)
1163 {
1164 super.OnItemLocationChanged(old_owner, new_owner);
1165
1166 PlayerBase relatedPlayer = PlayerBase.Cast(old_owner);
1167 PlayerBase playerNew = PlayerBase.Cast(new_owner);
1168
1169 if (!relatedPlayer && playerNew)
1170 relatedPlayer = playerNew;
1171
1172 if (relatedPlayer && relatedPlayer.GetPerformedActionID() != -1)
1173 {
1174 ActionManagerBase actionMgr = relatedPlayer.GetActionManager();
1175 if (actionMgr)
1176 {
1177 ActionBase currentAction = actionMgr.GetRunningAction();
1178 if (currentAction)
1179 currentAction.OnItemLocationChanged(this);
1180 }
1181 }
1182
1183 Man ownerPlayerOld = null;
1184 Man ownerPlayerNew = null;
1185
1186 if (old_owner)
1187 {
1188 if (old_owner.IsMan())
1189 {
1190 ownerPlayerOld = Man.Cast(old_owner);
1191 }
1192 else
1193 {
1194 ownerPlayerOld = Man.Cast(old_owner.GetHierarchyRootPlayer());
1195 }
1196 }
1197 else
1198 {
1199 if (new_owner && IsElectricAppliance() && GetCompEM() && GetCompEM().IsPlugged())
1200 {
1202
1203 if (!action || !playerNew || playerNew.GetPerformedActionID() != action.GetID())
1204 {
1205 GetCompEM().UnplugThis();
1206 }
1207 }
1208 }
1209
1210 if (new_owner)
1211 {
1212 if (new_owner.IsMan())
1213 {
1214 ownerPlayerNew = Man.Cast(new_owner);
1215 }
1216 else
1217 {
1218 ownerPlayerNew = Man.Cast(new_owner.GetHierarchyRootPlayer());
1219 }
1220 }
1221
1222 if (ownerPlayerOld != ownerPlayerNew)
1223 {
1224 if (ownerPlayerOld)
1225 {
1226 array<EntityAI> subItemsExit = new array<EntityAI>;
1227 GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER,subItemsExit);
1228 for (int i = 0; i < subItemsExit.Count(); i++)
1229 {
1230 ItemBase itemExit = ItemBase.Cast(subItemsExit.Get(i));
1231 itemExit.OnInventoryExit(ownerPlayerOld);
1232 }
1233 }
1234
1235 if (ownerPlayerNew)
1236 {
1237 array<EntityAI> subItemsEnter = new array<EntityAI>;
1238 GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER,subItemsEnter);
1239 for (int j = 0; j < subItemsEnter.Count(); j++)
1240 {
1241 ItemBase itemEnter = ItemBase.Cast(subItemsEnter.Get(j));
1242 itemEnter.OnInventoryEnter(ownerPlayerNew);
1243 }
1244 }
1245 }
1246 else if (ownerPlayerNew != null)
1247 {
1248 PlayerBase nplayer;
1249 if (PlayerBase.CastTo(nplayer, ownerPlayerNew))
1250 {
1251 array<EntityAI> subItemsUpdate = new array<EntityAI>;
1252 GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER,subItemsUpdate);
1253 for (int k = 0; k < subItemsUpdate.Count(); k++)
1254 {
1255 ItemBase itemUpdate = ItemBase.Cast(subItemsUpdate.Get(k));
1256 itemUpdate.UpdateQuickbarShortcutVisibility(nplayer);
1257 }
1258 }
1259 }
1260
1261 if (old_owner)
1262 old_owner.OnChildItemRemoved(this);
1263 if (new_owner)
1264 new_owner.OnChildItemReceived(this);
1265 }
1266
1267 // -------------------------------------------------------------------------------
1268 override void EEDelete(EntityAI parent)
1269 {
1270 super.EEDelete(parent);
1271 PlayerBase player = PlayerBase.Cast(GetHierarchyRootPlayer());
1272 if (player)
1273 {
1274 OnInventoryExit(player);
1275
1276 if (player.IsAlive())
1277 {
1278 int r_index = player.GetHumanInventory().FindUserReservedLocationIndex(this);
1279 if (r_index >= 0)
1280 {
1282 player.GetHumanInventory().GetUserReservedLocation(r_index,r_il);
1283
1284 player.GetHumanInventory().ClearUserReservedLocationAtIndex(r_index);
1285 int r_type = r_il.GetType();
1286 if (r_type == InventoryLocationType.CARGO || r_type == InventoryLocationType.PROXYCARGO)
1287 {
1288 r_il.GetParent().GetOnReleaseLock().Invoke(this);
1289 }
1290 else if (r_type == InventoryLocationType.ATTACHMENT)
1291 {
1292 r_il.GetParent().GetOnAttachmentReleaseLock().Invoke(this, r_il.GetSlot());
1293 }
1294
1295 }
1296
1297 player.RemoveQuickBarEntityShortcut(this);
1298 }
1299 }
1300 }
1301 // -------------------------------------------------------------------------------
1302 override void EEKilled(Object killer)
1303 {
1304 super.EEKilled(killer);
1305
1307 if (killer && killer.IsFireplace() && CanExplodeInFire())
1308 {
1309 if (GetTemperature() >= GameConstants.ITEM_TEMPERATURE_TO_EXPLODE_MIN)
1310 {
1311 if (IsMagazine())
1312 {
1313 if (Magazine.Cast(this).GetAmmoCount() > 0)
1314 {
1315 ExplodeAmmo();
1316 }
1317 }
1318 else
1319 {
1320 Explode(DamageType.EXPLOSION);
1321 }
1322 }
1323 }
1324 }
1325
1326 override void OnWasAttached(EntityAI parent, int slot_id)
1327 {
1328 MiscGameplayFunctions.RemoveAllAttachedChildrenByTypename(this, {Bolt_Base});
1329
1330 super.OnWasAttached(parent, slot_id);
1331
1332 if (HasQuantity())
1333 UpdateNetSyncVariableFloat("m_VarQuantity", GetQuantityMin(), GetQuantityMax());
1334
1335 if ((g_Game.IsServer() || !g_Game.IsMultiplayer()) && CanPlayAttachSound()) // single player or server side multiplayer
1336 StartItemSoundServer(SoundConstants.ITEM_ATTACH, slot_id);
1337 }
1338
1339 override void OnWasDetached(EntityAI parent, int slot_id)
1340 {
1341 super.OnWasDetached(parent, slot_id);
1342
1343 if (HasQuantity())
1344 UpdateNetSyncVariableFloat("m_VarQuantity", GetQuantityMin(), GetQuantityMax());
1345
1346 if ((g_Game.IsServer() || !g_Game.IsMultiplayer()) && CanPlayDetachSound()) // single player or server side multiplayer
1347 StartItemSoundServer(SoundConstants.ITEM_DETACH, slot_id);
1348 }
1349
1350 override string ChangeIntoOnAttach(string slot)
1351 {
1352 int idx;
1353 TStringArray inventory_slots = new TStringArray;
1354 TStringArray attach_types = new TStringArray;
1355
1356 ConfigGetTextArray("ChangeInventorySlot",inventory_slots);
1357 if (inventory_slots.Count() < 1) //is string
1358 {
1359 inventory_slots.Insert(ConfigGetString("ChangeInventorySlot"));
1360 attach_types.Insert(ConfigGetString("ChangeIntoOnAttach"));
1361 }
1362 else //is array
1363 {
1364 ConfigGetTextArray("ChangeIntoOnAttach",attach_types);
1365 }
1366
1367 idx = inventory_slots.Find(slot);
1368 if (idx < 0)
1369 return "";
1370
1371 return attach_types.Get(idx);
1372 }
1373
1374 override string ChangeIntoOnDetach()
1375 {
1376 int idx = -1;
1377 string slot;
1378
1379 TStringArray inventory_slots = new TStringArray;
1380 TStringArray detach_types = new TStringArray;
1381
1382 this.ConfigGetTextArray("ChangeInventorySlot",inventory_slots);
1383 if (inventory_slots.Count() < 1) //is string
1384 {
1385 inventory_slots.Insert(this.ConfigGetString("ChangeInventorySlot"));
1386 detach_types.Insert(this.ConfigGetString("ChangeIntoOnDetach"));
1387 }
1388 else //is array
1389 {
1390 this.ConfigGetTextArray("ChangeIntoOnDetach",detach_types);
1391 if (detach_types.Count() < 1)
1392 detach_types.Insert(this.ConfigGetString("ChangeIntoOnDetach"));
1393 }
1394
1395 for (int i = 0; i < inventory_slots.Count(); i++)
1396 {
1397 slot = inventory_slots.Get(i);
1398 }
1399
1400 if (slot != "")
1401 {
1402 if (detach_types.Count() == 1)
1403 idx = 0;
1404 else
1405 idx = inventory_slots.Find(slot);
1406 }
1407 if (idx < 0)
1408 return "";
1409
1410 return detach_types.Get(idx);
1411 }
1412
1414 {
1415 //timer
1416 ref Timer explode_timer = new Timer(CALL_CATEGORY_SYSTEM);
1417
1418 //min/max time
1419 float min_time = 1;
1420 float max_time = 3;
1421 float delay = Math.RandomFloat(min_time, max_time);
1422
1423 explode_timer.Run(delay, this, "DoAmmoExplosion");
1424 }
1425
1427 {
1428 Magazine magazine = Magazine.Cast(this);
1429 int pop_sounds_count = 6;
1430 string pop_sounds[ 6 ] = { "ammopops_1","ammopops_2","ammopops_3","ammopops_4","ammopops_5","ammopops_6" };
1431
1432 //play sound
1433 int sound_idx = Math.RandomInt(0, pop_sounds_count - 1);
1434 string sound_name = pop_sounds[ sound_idx ];
1435 g_Game.CreateSoundOnObject(this, sound_name, 20, false);
1436
1437 //remove ammo count
1438 magazine.ServerAddAmmoCount(-1);
1439
1440 //if condition then repeat -> ExplodeAmmo
1441 float min_temp_to_explode = 100; //min temperature for item to explode
1442
1443 if (magazine.GetAmmoCount() > 0 && GetTemperature() >= min_temp_to_explode) //TODO ? add check for parent -> fireplace
1444 {
1445 ExplodeAmmo();
1446 }
1447 }
1448
1449 // -------------------------------------------------------------------------------
1450 override void EEHitBy(TotalDamageResult damageResult, int damageType, EntityAI source, int component, string dmgZone, string ammo, vector modelPos, float speedCoef)
1451 {
1452 super.EEHitBy(damageResult, damageType, source, component, dmgZone, ammo, modelPos, speedCoef);
1453
1454 const int CHANCE_DAMAGE_CARGO = 4;
1455 const int CHANCE_DAMAGE_ATTACHMENT = 1;
1456 const int CHANCE_DAMAGE_NOTHING = 2;
1457
1458 if (IsClothing() || IsContainer() || IsItemTent())
1459 {
1460 float dmg = damageResult.GetDamage("","Health") * -0.5;
1461 int chances;
1462 int rnd;
1463
1464 if (GetInventory().GetCargo())
1465 {
1466 chances = CHANCE_DAMAGE_CARGO + CHANCE_DAMAGE_ATTACHMENT + CHANCE_DAMAGE_NOTHING;
1467 rnd = Math.RandomInt(0,chances);
1468
1469 if (rnd < CHANCE_DAMAGE_CARGO)
1470 {
1471 DamageItemInCargo(dmg);
1472 }
1473 else if (rnd < (chances - CHANCE_DAMAGE_NOTHING))
1474 {
1476 }
1477 }
1478 else
1479 {
1480 chances = CHANCE_DAMAGE_ATTACHMENT + CHANCE_DAMAGE_NOTHING;
1481 rnd = Math.RandomInt(0,chances);
1482
1483 if (rnd < CHANCE_DAMAGE_ATTACHMENT)
1484 {
1486 }
1487 }
1488 }
1489 }
1490
1491 bool DamageItemInCargo(float damage)
1492 {
1493 CargoBase cargo = GetInventory().GetCargo();
1494 if (cargo)
1495 {
1496 int item_count = cargo.GetItemCount();
1497 if (item_count > 0)
1498 {
1499 int random_pick = Math.RandomInt(0, item_count);
1500 ItemBase item = ItemBase.Cast(cargo.GetItem(random_pick));
1501 if (!item.IsExplosive())
1502 {
1503 item.AddHealth("","",damage);
1504 return true;
1505 }
1506 }
1507 }
1508 return false;
1509 }
1510
1511 bool DamageItemAttachments(float damage)
1512 {
1513 GameInventory inventory = GetInventory();
1514 int attachment_count = inventory.AttachmentCount();
1515 if (attachment_count > 0)
1516 {
1517 int random_pick = Math.RandomInt(0, attachment_count);
1518 ItemBase attachment = ItemBase.Cast(inventory.GetAttachmentFromIndex(random_pick));
1519 if (!attachment.IsExplosive())
1520 {
1521 attachment.AddHealth("","",damage);
1522 return true;
1523 }
1524 }
1525 return false;
1526 }
1527
1528 override bool IsSplitable()
1529 {
1530 return m_CanThisBeSplit;
1531 }
1532 //----------------
1533 override bool CanBeSplit()
1534 {
1535 if (IsSplitable() && (GetQuantity() > 1))
1536 return GetInventory().CanRemoveEntity();
1537
1538 return false;
1539 }
1540
1541 protected bool ShouldSplitQuantity(float quantity)
1542 {
1543 // don't call 'CanBeSplit' here, too strict and will introduce a freeze-crash when dismantling fence with a fireplace nearby
1544 if (!IsSplitable())
1545 return false;
1546
1547 // nothing to split?
1548 if (GetQuantity() <= 1)
1549 return false;
1550
1551 // check if we should re-use the item instead of creating a new copy?
1552 // implicit cast to int, if 'IsSplitable' returns true, these values are assumed ints
1553 int delta = GetQuantity() - quantity;
1554 if (delta == 0)
1555 return false;
1556
1557 // valid to split
1558 return true;
1559 }
1560
1561 override void SplitIntoStackMaxClient(EntityAI destination_entity, int slot_id )
1562 {
1563 if (g_Game.IsClient())
1564 {
1566 {
1569 ctx.Write(1);
1570 ItemBase i1 = this; // @NOTE: workaround for correct serialization
1571 ctx.Write(i1);
1572 ctx.Write(destination_entity);
1573 ctx.Write(true);
1574 ctx.Write(slot_id);
1575 ctx.Send();
1576 }
1577 }
1578 else if (!g_Game.IsMultiplayer())
1579 {
1580 SplitIntoStackMax(destination_entity, slot_id, PlayerBase.Cast(g_Game.GetPlayer()));
1581 }
1582 }
1583
1584 void SplitIntoStackMax(EntityAI destination_entity, int slot_id, PlayerBase player)
1585 {
1586 float split_quantity_new;
1587 ItemBase new_item;
1588 float quantity = GetQuantity();
1589 float stack_max = GetTargetQuantityMax(slot_id);
1591
1592 if (destination_entity && slot_id != -1 && InventorySlots.IsSlotIdValid(slot_id))
1593 {
1594 if (stack_max <= GetQuantity())
1595 split_quantity_new = stack_max;
1596 else
1597 split_quantity_new = GetQuantity();
1598
1599 if (ShouldSplitQuantity(split_quantity_new))
1600 {
1601 new_item = ItemBase.Cast(destination_entity.GetInventory().CreateAttachmentEx(this.GetType(), slot_id));
1602 if (new_item)
1603 {
1604 new_item.SetResultOfSplit(true);
1605 MiscGameplayFunctions.TransferItemProperties(this, new_item);
1606 AddQuantity(-split_quantity_new, false, true);
1607 new_item.SetQuantity(split_quantity_new, false, true);
1608 }
1609 }
1610 }
1611 else if (destination_entity && slot_id == -1)
1612 {
1613 if (quantity > stack_max)
1614 split_quantity_new = stack_max;
1615 else
1616 split_quantity_new = quantity;
1617
1618 if (ShouldSplitQuantity(split_quantity_new))
1619 {
1620 GameInventory destinationInventory = destination_entity.GetInventory();
1621 if (destinationInventory.FindFreeLocationFor(this, FindInventoryLocationType.ANY, loc))
1622 {
1623 Object o = destinationInventory.LocationCreateEntity(loc, GetType(), ECE_IN_INVENTORY, RF_DEFAULT);
1624 new_item = ItemBase.Cast(o);
1625 }
1626
1627 if (new_item)
1628 {
1629 new_item.SetResultOfSplit(true);
1630 MiscGameplayFunctions.TransferItemProperties(this, new_item);
1631 AddQuantity(-split_quantity_new, false, true);
1632 new_item.SetQuantity(split_quantity_new, false, true);
1633 }
1634 }
1635 }
1636 else
1637 {
1638 if (stack_max != 0)
1639 {
1640 if (stack_max < GetQuantity())
1641 {
1642 split_quantity_new = GetQuantity() - stack_max;
1643 }
1644
1645 if (split_quantity_new == 0)
1646 {
1647 if (!g_Game.IsMultiplayer())
1648 player.PhysicalPredictiveDropItem(this);
1649 else
1650 player.ServerDropEntity(this);
1651 return;
1652 }
1653
1654 if (ShouldSplitQuantity(split_quantity_new))
1655 {
1656 new_item = ItemBase.Cast(g_Game.CreateObjectEx(GetType(), player.GetWorldPosition(), ECE_PLACE_ON_SURFACE));
1657
1658 if (new_item)
1659 {
1660 new_item.SetResultOfSplit(true);
1661 MiscGameplayFunctions.TransferItemProperties(this, new_item);
1662 SetQuantity(split_quantity_new, false, true);
1663 new_item.SetQuantity(stack_max, false, true);
1664 new_item.PlaceOnSurface();
1665 }
1666 }
1667 }
1668 }
1669 }
1670
1671 override void SplitIntoStackMaxEx(EntityAI destination_entity, int slot_id)
1672 {
1673 float split_quantity_new;
1674 ItemBase new_item;
1675 float quantity = GetQuantity();
1676 float stack_max = GetTargetQuantityMax(slot_id);
1678
1679 if (destination_entity && slot_id != -1 && InventorySlots.IsSlotIdValid(slot_id))
1680 {
1681 if (stack_max <= GetQuantity())
1682 split_quantity_new = stack_max;
1683 else
1684 split_quantity_new = GetQuantity();
1685
1686 if (ShouldSplitQuantity(split_quantity_new))
1687 {
1688 new_item = ItemBase.Cast(destination_entity.GetInventory().CreateAttachmentEx(this.GetType(), slot_id));
1689 if (new_item)
1690 {
1691 new_item.SetResultOfSplit(true);
1692 MiscGameplayFunctions.TransferItemProperties(this, new_item);
1693 AddQuantity(-split_quantity_new, false, true);
1694 new_item.SetQuantity(split_quantity_new, false, true);
1695 }
1696 }
1697 }
1698 else if (destination_entity && slot_id == -1)
1699 {
1700 if (quantity > stack_max)
1701 split_quantity_new = stack_max;
1702 else
1703 split_quantity_new = quantity;
1704
1705 if (ShouldSplitQuantity(split_quantity_new))
1706 {
1707 GameInventory destinationInventory = destination_entity.GetInventory();
1708 if (destinationInventory.FindFreeLocationFor(this, FindInventoryLocationType.ANY, loc))
1709 {
1710 Object o = destinationInventory.LocationCreateEntity(loc, GetType(), ECE_IN_INVENTORY, RF_DEFAULT);
1711 new_item = ItemBase.Cast(o);
1712 }
1713
1714 if (new_item)
1715 {
1716 new_item.SetResultOfSplit(true);
1717 MiscGameplayFunctions.TransferItemProperties(this, new_item);
1718 AddQuantity(-split_quantity_new, false, true);
1719 new_item.SetQuantity(split_quantity_new, false, true);
1720 }
1721 }
1722 }
1723 else
1724 {
1725 if (stack_max != 0)
1726 {
1727 if (stack_max < GetQuantity())
1728 {
1729 split_quantity_new = GetQuantity() - stack_max;
1730 }
1731
1732 if (ShouldSplitQuantity(split_quantity_new))
1733 {
1734 new_item = ItemBase.Cast(g_Game.CreateObjectEx(GetType(),GetWorldPosition(), ECE_PLACE_ON_SURFACE));
1735
1736 if (new_item)
1737 {
1738 new_item.SetResultOfSplit(true);
1739 MiscGameplayFunctions.TransferItemProperties(this, new_item);
1740 SetQuantity(split_quantity_new, false, true);
1741 new_item.SetQuantity(stack_max, false, true);
1742 new_item.PlaceOnSurface();
1743 }
1744 }
1745 }
1746 }
1747 }
1748
1750 {
1751 if (g_Game.IsClient())
1752 {
1754 {
1757 ctx.Write(4);
1758 ItemBase thiz = this; // @NOTE: workaround for correct serialization
1759 ctx.Write(thiz);
1760 dst.WriteToContext(ctx);
1761 ctx.Write(false);
1762 ctx.Send();
1763 }
1764 }
1765 else if (!g_Game.IsMultiplayer())
1766 {
1768 }
1769 }
1770
1771 void SplitIntoStackMaxCargoClient(EntityAI destination_entity, int idx, int row, int col)
1772 {
1773 if (g_Game.IsClient())
1774 {
1776 {
1779 ctx.Write(2);
1780 ItemBase dummy = this; // @NOTE: workaround for correct serialization
1781 ctx.Write(dummy);
1782 ctx.Write(destination_entity);
1783 ctx.Write(true);
1784 ctx.Write(idx);
1785 ctx.Write(row);
1786 ctx.Write(col);
1787 ctx.Send();
1788 }
1789 }
1790 else if (!g_Game.IsMultiplayer())
1791 {
1792 SplitIntoStackMaxCargo(destination_entity, idx, row, col);
1793 }
1794 }
1795
1800
1802 {
1803 float quantity = GetQuantity();
1804 float split_quantity_new;
1805 ItemBase new_item;
1806 if (dst.IsValid())
1807 {
1808 int slot_id = dst.GetSlot();
1809 float stack_max = GetTargetQuantityMax(slot_id);
1810
1811 if (quantity > stack_max)
1812 split_quantity_new = stack_max;
1813 else
1814 split_quantity_new = quantity;
1815
1816 if (ShouldSplitQuantity(split_quantity_new))
1817 {
1818 int flag = ECE_IN_INVENTORY;
1819 if (dst.GetType() == InventoryLocationType.GROUND)
1820 flag = ECE_PLACE_ON_SURFACE;
1821 new_item = ItemBase.Cast(GameInventory.LocationCreateEntity(dst, this.GetType(), flag, RF_DEFAULT));
1822
1823 if (new_item)
1824 {
1825 new_item.SetResultOfSplit(true);
1826 MiscGameplayFunctions.TransferItemProperties(this,new_item);
1827 AddQuantity(-split_quantity_new, false, true);
1828 new_item.SetQuantity(split_quantity_new, false, true);
1829 }
1830
1831 return new_item;
1832 }
1833 }
1834
1835 return null;
1836 }
1837
1838 void SplitIntoStackMaxCargo(EntityAI destination_entity, int idx, int row, int col)
1839 {
1840 float quantity = GetQuantity();
1841 float split_quantity_new;
1842 ItemBase new_item;
1843 if (destination_entity)
1844 {
1845 float stackable = GetTargetQuantityMax();
1846 if (quantity > stackable)
1847 split_quantity_new = stackable;
1848 else
1849 split_quantity_new = quantity;
1850
1851 if (ShouldSplitQuantity(split_quantity_new))
1852 {
1853 new_item = ItemBase.Cast(destination_entity.GetInventory().CreateEntityInCargoEx(this.GetType(), idx, row, col, false));
1854 if (new_item)
1855 {
1856 new_item.SetResultOfSplit(true);
1857 MiscGameplayFunctions.TransferItemProperties(this,new_item);
1858 AddQuantity(-split_quantity_new, false, true);
1859 new_item.SetQuantity(split_quantity_new, false, true);
1860 }
1861 }
1862 }
1863 }
1864
1866 {
1867 if (g_Game.IsClient())
1868 {
1870 {
1873 ctx.Write(3);
1874 ItemBase i1 = this; // @NOTE: workaround for correct serialization
1875 ctx.Write(i1);
1876 ItemBase destination_entity = this;
1877 ctx.Write(destination_entity);
1878 ctx.Write(true);
1879 ctx.Write(0);
1880 ctx.Send();
1881 }
1882 }
1883 else if (!g_Game.IsMultiplayer())
1884 {
1885 SplitIntoStackMaxHands(player);
1886 }
1887 }
1888
1890 {
1891 float quantity = GetQuantity();
1892 float split_quantity_new;
1893 ref ItemBase new_item;
1894 if (player)
1895 {
1896 float stackable = GetTargetQuantityMax();
1897 if (quantity > stackable)
1898 split_quantity_new = stackable;
1899 else
1900 split_quantity_new = quantity;
1901
1902 if (ShouldSplitQuantity(split_quantity_new))
1903 {
1904 EntityAI in_hands = player.GetHumanInventory().CreateInHands(this.GetType());
1905 new_item = ItemBase.Cast(in_hands);
1906 if (new_item)
1907 {
1908 new_item.SetResultOfSplit(true);
1909 MiscGameplayFunctions.TransferItemProperties(this,new_item);
1910 AddQuantity(-split_quantity_new, false, true);
1911 new_item.SetQuantity(split_quantity_new, false, true);
1912 }
1913 }
1914 }
1915 }
1916
1918 {
1919 float quantity = GetQuantity();
1920 float split_quantity_new = Math.Floor(quantity * 0.5);
1921
1922 if (!ShouldSplitQuantity(split_quantity_new))
1923 return;
1924
1925 int flag = ECE_IN_INVENTORY;
1926 if (dst.GetType() == InventoryLocationType.GROUND)
1927 flag = ECE_PLACE_ON_SURFACE;
1928 ItemBase new_item = ItemBase.Cast(GameInventory.LocationCreateEntity(dst, GetType(), flag, RF_DEFAULT));
1929
1930 if (new_item)
1931 {
1932 if (new_item.GetQuantityMax() < split_quantity_new)
1933 {
1934 split_quantity_new = new_item.GetQuantityMax();
1935 }
1936
1937 new_item.SetResultOfSplit(true);
1938 MiscGameplayFunctions.TransferItemProperties(this, new_item);
1939
1940 if (dst.IsValid() && dst.GetType() == InventoryLocationType.ATTACHMENT && split_quantity_new > 1)
1941 {
1942 AddQuantity(-1, false, true);
1943 new_item.SetQuantity(1, false, true);
1944 }
1945 else
1946 {
1947 AddQuantity(-split_quantity_new, false, true);
1948 new_item.SetQuantity(split_quantity_new, false, true);
1949 }
1950 }
1951 }
1952
1954 {
1955 float quantity = GetQuantity();
1956 float split_quantity_new = Math.Floor(quantity / 2);
1957
1958 if (!ShouldSplitQuantity(split_quantity_new))
1959 return;
1960
1962 bool found = player.GetInventory().FindFirstFreeLocationForNewEntity(GetType(), FindInventoryLocationType.ATTACHMENT, invloc);
1963
1964 ItemBase new_item;
1965 new_item = player.CreateCopyOfItemInInventoryOrGroundEx(this, true);
1966
1967 if (new_item)
1968 {
1969 if (new_item.GetQuantityMax() < split_quantity_new)
1970 {
1971 split_quantity_new = new_item.GetQuantityMax();
1972 }
1973 if (found && invloc.IsValid() && invloc.GetType() == InventoryLocationType.ATTACHMENT && split_quantity_new > 1)
1974 {
1975 AddQuantity(-1, false, true);
1976 new_item.SetQuantity(1, false, true);
1977 }
1978 else
1979 {
1980 AddQuantity(-split_quantity_new, false, true);
1981 new_item.SetQuantity(split_quantity_new, false, true);
1982 }
1983 }
1984 }
1985
1987 void OnQuantityChanged(float delta)
1988 {
1989 SetWeightDirty();
1990 ItemBase parent = ItemBase.Cast(GetHierarchyParent());
1991
1992 if (parent)
1993 parent.OnAttachmentQuantityChangedEx(this, delta);
1994
1995 if (IsLiquidContainer())
1996 {
1997 if (GetQuantityNormalized() <= 0.0)
1998 {
2000 }
2001 else if (GetLiquidType() == LIQUID_NONE)
2002 {
2003 ErrorEx("Undefined liquid type quantity changed, please define liquid type first! Using init value.",ErrorExSeverity.INFO);
2005 }
2006 }
2007 }
2008
2011 {
2012 // insert code here
2013 }
2014
2017 {
2019 }
2020
2021 override void EEHealthLevelChanged(int oldLevel, int newLevel, string zone)
2022 {
2023 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
2024
2025 if (g_Game.IsServer())
2026 {
2027 if (newLevel == GameConstants.STATE_RUINED)
2028 {
2030 EntityAI parent = GetHierarchyParent();
2031 if (parent && parent.IsFireplace())
2032 {
2033 CargoBase cargo = GetInventory().GetCargo();
2034 if (cargo)
2035 {
2036 for (int i = 0; i < cargo.GetItemCount(); ++i)
2037 {
2038 parent.GetInventory().TakeEntityToInventory(InventoryMode.SERVER, FindInventoryLocationType.CARGO, cargo.GetItem(i));
2039 }
2040 }
2041 }
2042 }
2043
2044 if (IsResultOfSplit())
2045 {
2046 // reset the splitting result flag, return to normal item behavior
2047 SetResultOfSplit(false);
2048 return;
2049 }
2050
2051 if (m_Cleanness != 0 && oldLevel < newLevel && newLevel != 0)
2052 {
2053 SetCleanness(0);//unclean the item upon damage dealt
2054 }
2055 }
2056 }
2057
2058 // just the split? TODO: verify
2059 override void OnRightClick()
2060 {
2061 super.OnRightClick();
2062
2063 if (CanBeSplit() && !GetDayZGame().IsLeftCtrlDown() && !g_Game.GetPlayer().GetInventory().HasInventoryReservation(this,null))
2064 {
2065 if (g_Game.IsClient())
2066 {
2068 {
2069 EntityAI root = GetHierarchyRoot();
2070 Man playerOwner = GetHierarchyRootPlayer();
2072
2073 // If we have no hierarchy root player and the root is the same as this item the source item is in the vicinity so we want to create the new split item there also
2074 if (!playerOwner && root && root == this)
2075 {
2077 }
2078 else
2079 {
2080 // Check if we can place the new split item in the same parent where the source item is placed in or otherwise drop it in vicinity
2081 GetInventory().GetCurrentInventoryLocation(dst);
2082 if (!dst.GetParent() || dst.GetParent() && !dst.GetParent().GetInventory().FindFreeLocationFor(this, FindInventoryLocationType.CARGO, dst))
2083 {
2084 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
2085 if (!player.GetInventory().FindFreeLocationFor(this, FindInventoryLocationType.CARGO, dst) || !playerOwner)
2086 {
2087 SetInventoryLocationToVicinityOrCurrent(player, dst); //dropping on the ground next to the spliting player
2088 }
2089 else
2090 {
2091 dst.SetCargo(dst.GetParent(), this, dst.GetIdx(), dst.GetRow(), dst.GetCol(), dst.GetFlip());
2092 /* hacky solution to check reservation of "this" item instead of null since the gamecode is checking null against null and returning reservation=true incorrectly
2093 this shouldnt cause issues within this scope*/
2094 if (g_Game.GetPlayer().GetInventory().HasInventoryReservation(this, dst))
2095 {
2097 }
2098 else
2099 {
2100 g_Game.GetPlayer().GetInventory().AddInventoryReservationEx(null, dst, GameInventory.c_InventoryReservationTimeoutShortMS);
2101 }
2102 }
2103 }
2104 }
2105
2108 ctx.Write(4);
2109 ItemBase thiz = this; // @NOTE: workaround for correct serialization
2110 ctx.Write(thiz);
2111 dst.WriteToContext(ctx);
2112 ctx.Write(true); // dummy
2113 ctx.Send();
2114 }
2115 }
2116 else if (!g_Game.IsMultiplayer())
2117 {
2118 SplitItem(PlayerBase.Cast(g_Game.GetPlayer()));
2119 }
2120 }
2121 }
2122
2124 {
2125 if (root)
2126 {
2127 vector m4[4];
2128 root.GetTransform(m4);
2129 dst.SetGround(this, m4);
2130 }
2131 else
2132 {
2133 GetInventory().GetCurrentInventoryLocation(dst);
2134 }
2135 }
2136
2137 override bool CanBeCombined(EntityAI other_item, bool reservation_check = true, bool stack_max_limit = false)
2138 {
2139 //TODO: delete check zero quantity check after fix double posts hands fsm events
2140 if (!other_item || GetType() != other_item.GetType() || (IsFullQuantity() && other_item.GetQuantity() > 0) || other_item == this)
2141 return false;
2142
2143 if (GetHealthLevel() == GameConstants.STATE_RUINED || other_item.GetHealthLevel() == GameConstants.STATE_RUINED)
2144 return false;
2145
2146 //can_this_be_combined = ConfigGetBool("canBeSplit");
2148 return false;
2149
2150
2151 Magazine mag = Magazine.Cast(this);
2152 if (mag)
2153 {
2154 if (mag.GetAmmoCount() >= mag.GetAmmoMax())
2155 return false;
2156
2157 if (stack_max_limit)
2158 {
2159 Magazine other_mag = Magazine.Cast(other_item);
2160 if (other_item)
2161 {
2162 if (mag.GetAmmoCount() + other_mag.GetAmmoCount() > mag.GetAmmoMax())
2163 return false;
2164 }
2165
2166 }
2167 }
2168 else
2169 {
2170 //TODO: delete check zero quantity check after fix double posts hands fsm events
2171 if (GetQuantity() >= GetQuantityMax() && other_item.GetQuantity() > 0 )
2172 return false;
2173
2174 if (stack_max_limit && (GetQuantity() + other_item.GetQuantity() > GetQuantityMax()))
2175 return false;
2176 }
2177
2178 PlayerBase player = null;
2179 if (CastTo(player, GetHierarchyRootPlayer())) //false when attached to player's attachment slot
2180 {
2181 if (player.GetInventory().HasAttachment(this))
2182 return false;
2183
2184 if (player.IsItemsToDelete())
2185 return false;
2186 }
2187
2188 if (reservation_check && (GetInventory().HasInventoryReservation(this, null) || other_item.GetInventory().HasInventoryReservation(other_item, null)))
2189 return false;
2190
2191 int slotID;
2192 string slotName;
2193 if (GetInventory().GetCurrentAttachmentSlotInfo(slotID,slotName) && GetHierarchyParent().GetInventory().GetSlotLock(slotID))
2194 return false;
2195
2196 return true;
2197 }
2198
2199 bool IsCombineAll(ItemBase other_item, bool use_stack_max = false)
2200 {
2201 return ComputeQuantityUsed(other_item, use_stack_max) == other_item.GetQuantity();
2202 }
2203
2205 {
2206 return m_IsResultOfSplit;
2207 }
2208
2209 void SetResultOfSplit(bool value)
2210 {
2211 m_IsResultOfSplit = value;
2212 }
2213
2214 int ComputeQuantityUsed(ItemBase other_item, bool use_stack_max = true)
2215 {
2216 return ComputeQuantityUsedEx(other_item, use_stack_max);
2217 }
2218
2219 float ComputeQuantityUsedEx(ItemBase other_item, bool use_stack_max = true)
2220 {
2221 float other_item_quantity = other_item.GetQuantity();
2222 float this_free_space;
2223
2224 float stack_max = GetQuantityMax();
2225
2226 this_free_space = stack_max - GetQuantity();
2227
2228 if (other_item_quantity > this_free_space)
2229 {
2230 return this_free_space;
2231 }
2232 else
2233 {
2234 return other_item_quantity;
2235 }
2236 }
2237
2238 override void CombineItemsEx(EntityAI entity2, bool use_stack_max = true)
2239 {
2240 CombineItems(ItemBase.Cast(entity2),use_stack_max);
2241 }
2242
2243 void CombineItems(ItemBase other_item, bool use_stack_max = true)
2244 {
2245 if (!CanBeCombined(other_item, false))
2246 return;
2247
2248 if (!IsMagazine() && other_item)
2249 {
2250 float quantity_used = ComputeQuantityUsedEx(other_item,use_stack_max);
2251 if (quantity_used != 0)
2252 {
2253 float hp1 = GetHealth01("","");
2254 float hp2 = other_item.GetHealth01("","");
2255 float hpResult = ((hp1*GetQuantity()) + (hp2*quantity_used));
2256 hpResult = hpResult / (GetQuantity() + quantity_used);
2257
2258 hpResult *= GetMaxHealth();
2259 Math.Round(hpResult);
2260 SetHealth("", "Health", hpResult);
2261
2262 AddQuantity(quantity_used);
2263 other_item.AddQuantity(-quantity_used);
2264 }
2265 }
2266 OnCombine(other_item);
2267 }
2268
2269 void OnCombine(ItemBase other_item)
2270 {
2271 #ifdef SERVER
2272 if (!GetHierarchyRootPlayer() && GetHierarchyParent())
2273 GetHierarchyParent().IncreaseLifetimeUp();
2274 #endif
2275 };
2276
2277 void GetRecipesActions(Man player, out TSelectableActionInfoArray outputList)
2278 {
2279 PlayerBase p = PlayerBase.Cast(player);
2280
2281 array<int> recipesIds = p.m_Recipes;
2282 PluginRecipesManager moduleRecipesManager = PluginRecipesManager.Cast(GetPlugin(PluginRecipesManager));
2283 if (moduleRecipesManager)
2284 {
2285 EntityAI itemInHands = player.GetEntityInHands();
2286 moduleRecipesManager.GetValidRecipes(ItemBase.Cast(this), ItemBase.Cast(itemInHands), recipesIds, p);
2287 }
2288
2289 for (int i = 0;i < recipesIds.Count(); i++)
2290 {
2291 int key = recipesIds.Get(i);
2292 string recipeName = moduleRecipesManager.GetRecipeName(key);
2293 outputList.Insert(new TSelectableActionInfo(SAT_CRAFTING, key, recipeName));
2294 }
2295 }
2296
2297 // -------------------------------------------------------------------------
2298 override void GetDebugActions(out TSelectableActionInfoArrayEx outputList)
2299 {
2300 super.GetDebugActions(outputList);
2301
2302 //quantity
2303 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_QUANTITY, "Quantity +20%", FadeColors.LIGHT_GREY));
2304 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_QUANTITY, "Quantity -20%", FadeColors.LIGHT_GREY));
2305 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SET_QUANTITY_0, "Set Quantity 0", FadeColors.LIGHT_GREY));
2306 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SET_MAX_QUANTITY, "Set Quantity Max", FadeColors.LIGHT_GREY));
2307 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
2308
2309 //health
2310 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_HEALTH, "Health +20%", FadeColors.LIGHT_GREY));
2311 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_HEALTH, "Health -20%", FadeColors.LIGHT_GREY));
2312 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.DESTROY_HEALTH, "Health 0", FadeColors.LIGHT_GREY));
2313 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
2314 //temperature
2315 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_TEMPERATURE, "Temperature +20", FadeColors.LIGHT_GREY));
2316 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_TEMPERATURE, "Temperature -20", FadeColors.LIGHT_GREY));
2317 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.FLIP_FROZEN, "Toggle Frozen", FadeColors.LIGHT_GREY));
2318 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
2319
2320 //wet
2321 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_WETNESS, "Wetness +20", FadeColors.LIGHT_GREY));
2322 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_WETNESS, "Wetness -20", FadeColors.LIGHT_GREY));
2323 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
2324
2325 //liquidtype
2326 if (IsLiquidContainer())
2327 {
2328 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.LIQUIDTYPE_UP, "LiquidType Next", FadeColors.LIGHT_GREY));
2329 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.LIQUIDTYPE_DOWN, "LiquidType Previous", FadeColors.LIGHT_GREY));
2330 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
2331 }
2332
2333 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.MAKE_SPECIAL, "Make Special", FadeColors.LIGHT_GREY));
2334 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
2335
2336 // watch
2337 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.WATCH_ITEM, "Watch (CTRL-Z)", FadeColors.LIGHT_GREY));
2338 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.WATCH_PLAYER, "Watch Player", FadeColors.LIGHT_GREY));
2339 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
2340
2341 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.DELETE, "Delete", FadeColors.RED));
2342
2344 GetInventory().GetCurrentInventoryLocation(loc);
2345 if (!loc || loc.GetType() == InventoryLocationType.GROUND)
2346 {
2347 if (Gizmo_IsSupported())
2348 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.GIZMO_OBJECT, "Gizmo Object", FadeColors.LIGHT_GREY));
2349 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.GIZMO_PHYSICS, "Gizmo Physics (SP Only)", FadeColors.LIGHT_GREY)); // intentionally allowed for testing physics desync
2350 }
2351
2352 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
2353 }
2354
2355 // -------------------------------------------------------------------------
2356 // -------------------------------------------------------------------------
2357 // -------------------------------------------------------------------------
2358 override bool OnAction(int action_id, Man player, ParamsReadContext ctx)
2359 {
2360 super.OnAction(action_id, player, ctx);
2361
2362 if (g_Game.IsClient() || !g_Game.IsMultiplayer())
2363 {
2364 switch (action_id)
2365 {
2366 case EActions.GIZMO_OBJECT:
2367 if (GetGizmoApi())
2368 GetGizmoApi().SelectObject(this);
2369 return true;
2370 case EActions.GIZMO_PHYSICS:
2371 if (GetGizmoApi())
2372 GetGizmoApi().SelectPhysics(GetPhysics());
2373 return true;
2374 }
2375 }
2376
2377 if (g_Game.IsServer())
2378 {
2379 switch (action_id)
2380 {
2381 case EActions.DELETE:
2382 Delete();
2383 return true;
2384 }
2385 }
2386
2387 if (action_id >= EActions.RECIPES_RANGE_START && action_id < EActions.RECIPES_RANGE_END)
2388 {
2389 PluginRecipesManager plugin_recipes_manager = PluginRecipesManager.Cast(GetPlugin(PluginRecipesManager));
2390 int idWithoutOffset = action_id - EActions.RECIPES_RANGE_START;
2391 PlayerBase p = PlayerBase.Cast(player);
2392 if (EActions.RECIPES_RANGE_START < 1000)
2393 {
2394 float anim_length = plugin_recipes_manager.GetRecipeLengthInSecs(idWithoutOffset);
2395 float specialty_weight = plugin_recipes_manager.GetRecipeSpecialty(idWithoutOffset);
2396 }
2397 }
2398 #ifndef SERVER
2399 else if (action_id == EActions.WATCH_PLAYER)
2400 {
2401 PluginDeveloper.SetDeveloperItemClientEx(player);
2402 }
2403 #endif
2404 if (g_Game.IsServer())
2405 {
2406 if (action_id >= EActions.DEBUG_ITEM_WATCH_BUTTON_RANGE_START && action_id < EActions.DEBUG_ITEM_WATCH_BUTTON_RANGE_END)
2407 {
2408 int id = action_id - EActions.DEBUG_ITEM_WATCH_BUTTON_RANGE_START;
2409 OnDebugButtonPressServer(id + 1);
2410 }
2411
2412 else if (action_id >= EActions.DEBUG_AGENTS_RANGE_INJECT_START && action_id < EActions.DEBUG_AGENTS_RANGE_INJECT_END)
2413 {
2414 int agent_id = action_id - EActions.DEBUG_AGENTS_RANGE_INJECT_START;
2415 InsertAgent(agent_id,100);
2416 }
2417
2418 else if (action_id >= EActions.DEBUG_AGENTS_RANGE_REMOVE_START && action_id < EActions.DEBUG_AGENTS_RANGE_REMOVE_END)
2419 {
2420 int agent_id2 = action_id - EActions.DEBUG_AGENTS_RANGE_REMOVE_START;
2421 RemoveAgent(agent_id2);
2422 }
2423
2424 else if (action_id == EActions.ADD_QUANTITY)
2425 {
2426 if (IsMagazine())
2427 {
2428 Magazine mag = Magazine.Cast(this);
2429 mag.ServerSetAmmoCount(mag.GetAmmoCount() + mag.GetAmmoMax() * 0.2);
2430 }
2431 else
2432 {
2433 AddQuantity(GetQuantityMax() * 0.2);
2434 }
2435
2436 if (m_EM)
2437 {
2438 m_EM.AddEnergy(m_EM.GetEnergyMax() * 0.2);
2439 }
2440 //PrintVariables();
2441 }
2442
2443 else if (action_id == EActions.REMOVE_QUANTITY) //Quantity -20%
2444 {
2445 if (IsMagazine())
2446 {
2447 Magazine mag2 = Magazine.Cast(this);
2448 mag2.ServerSetAmmoCount(mag2.GetAmmoCount() - mag2.GetAmmoMax() * 0.2);
2449 }
2450 else
2451 {
2452 AddQuantity(- GetQuantityMax() * 0.2);
2453 }
2454 if (m_EM)
2455 {
2456 m_EM.AddEnergy(- m_EM.GetEnergyMax() * 0.2);
2457 }
2458 //PrintVariables();
2459 }
2460
2461 else if (action_id == EActions.SET_QUANTITY_0) //SetMaxQuantity
2462 {
2463 SetQuantity(0);
2464
2465 if (m_EM)
2466 {
2467 m_EM.SetEnergy(0);
2468 }
2469 }
2470
2471 else if (action_id == EActions.SET_MAX_QUANTITY) //SetMaxQuantity
2472 {
2474
2475 if (m_EM)
2476 {
2477 m_EM.SetEnergy(m_EM.GetEnergyMax());
2478 }
2479 }
2480
2481 else if (action_id == EActions.ADD_HEALTH)
2482 {
2483 AddHealth("","",GetMaxHealth("","Health")/5);
2484 }
2485 else if (action_id == EActions.REMOVE_HEALTH)
2486 {
2487 AddHealth("","",-GetMaxHealth("","Health")/5);
2488 }
2489 else if (action_id == EActions.DESTROY_HEALTH)
2490 {
2491 SetHealth01("","",0);
2492 }
2493 else if (action_id == EActions.WATCH_ITEM)
2494 {
2496 mid.RegisterDebugItem(ItemBase.Cast(this), PlayerBase.Cast(player));
2497 #ifdef DEVELOPER
2498 SetDebugDeveloper_item(this);
2499 #endif
2500 }
2501
2502 else if (action_id == EActions.ADD_TEMPERATURE)
2503 {
2504 AddTemperature(20);
2505 //PrintVariables();
2506 }
2507
2508 else if (action_id == EActions.REMOVE_TEMPERATURE)
2509 {
2510 AddTemperature(-20);
2511 //PrintVariables();
2512 }
2513
2514 else if (action_id == EActions.FLIP_FROZEN)
2515 {
2516 SetFrozen(!GetIsFrozen());
2517 //PrintVariables();
2518 }
2519
2520 else if (action_id == EActions.ADD_WETNESS)
2521 {
2522 AddWet(GetWetMax()/5);
2523 //PrintVariables();
2524 }
2525
2526 else if (action_id == EActions.REMOVE_WETNESS)
2527 {
2528 AddWet(-GetWetMax()/5);
2529 //PrintVariables();
2530 }
2531
2532 else if (action_id == EActions.LIQUIDTYPE_UP)
2533 {
2534 int curr_type = GetLiquidType();
2535 SetLiquidType(curr_type * 2);
2536 //AddWet(1);
2537 //PrintVariables();
2538 }
2539
2540 else if (action_id == EActions.LIQUIDTYPE_DOWN)
2541 {
2542 int curr_type2 = GetLiquidType();
2543 SetLiquidType(curr_type2 / 2);
2544 }
2545
2546 else if (action_id == EActions.MAKE_SPECIAL)
2547 {
2548 auto debugParams = DebugSpawnParams.WithPlayer(player);
2549 OnDebugSpawnEx(debugParams);
2550 }
2551
2552 }
2553
2554
2555 return false;
2556 }
2557
2558 // -------------------------------------------------------------------------
2559
2560
2564
2566 void OnActivatedByItem(notnull ItemBase item);
2567
2568 //----------------------------------------------------------------
2569 //returns true if item is able to explode when put in fire
2571 {
2572 return false;
2573 }
2574
2575 //----------------------------------------------------------------
2576 bool CanEat()
2577 {
2578 return true;
2579 }
2580
2581 //----------------------------------------------------------------
2583 {
2584 return true;
2585 }
2586
2587 //----------------------------------------------------------------
2588 //has FoodStages in config?
2590 {
2591 string config_path = string.Format("CfgVehicles %1 Food FoodStages", GetType());
2592 return g_Game.ConfigIsExisting(config_path);
2593 }
2594
2596 FoodStage GetFoodStage()
2597 {
2598 return null;
2599 }
2600
2602 {
2603 return false;
2604 }
2605
2607 {
2608 return false;
2609 }
2610
2612 void RefreshAudioVisualsOnClient( CookingMethodType cooking_method, bool is_done, bool is_empty, bool is_burned );
2614
2615 //----------------------------------------------------------------
2616 bool CanRepair(ItemBase item_repair_kit)
2617 {
2618 PluginRepairing module_repairing = PluginRepairing.Cast(GetPlugin(PluginRepairing));
2619 return module_repairing.CanRepair(this, item_repair_kit);
2620 }
2621
2622 //----------------------------------------------------------------
2623 bool Repair(PlayerBase player, ItemBase item_repair_kit, float specialty_weight)
2624 {
2625 PluginRepairing module_repairing = PluginRepairing.Cast(GetPlugin(PluginRepairing));
2626 return module_repairing.Repair(player, this, item_repair_kit, specialty_weight);
2627 }
2628
2629 //----------------------------------------------------------------
2631 {
2632 /*
2633 vector v_size = this.ConfigGetVector("itemSize");
2634 int v_size_x = v_size[0];
2635 int v_size_y = v_size[1];
2636 int size = v_size_x * v_size_y;
2637 return size;
2638 */
2639
2640 return 1;
2641 }
2642
2643 //----------------------------------------------------------------
2644 //Override for allowing seemingly unallowed moves when two clients send a conflicting message simultaneously
2646 {
2647 return m_CanBeMovedOverride;
2648 }
2649
2650 //----------------------------------------------------------------
2651 //Override for allowing seemingly unallowed moves when two clients send a conflicting message simultaneously
2652 void SetCanBeMovedOverride(bool setting)
2653 {
2654 m_CanBeMovedOverride = setting;
2655 }
2656
2657 //----------------------------------------------------------------
2665 void MessageToOwnerStatus(string text)
2666 {
2667 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
2668
2669 if (player)
2670 {
2671 player.MessageStatus(text);
2672 }
2673 }
2674
2675 //----------------------------------------------------------------
2683 void MessageToOwnerAction(string text)
2684 {
2685 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
2686
2687 if (player)
2688 {
2689 player.MessageAction(text);
2690 }
2691 }
2692
2693 //----------------------------------------------------------------
2701 void MessageToOwnerFriendly(string text)
2702 {
2703 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
2704
2705 if (player)
2706 {
2707 player.MessageFriendly(text);
2708 }
2709 }
2710
2711 //----------------------------------------------------------------
2719 void MessageToOwnerImportant(string text)
2720 {
2721 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
2722
2723 if (player)
2724 {
2725 player.MessageImportant(text);
2726 }
2727 }
2728
2729 override bool IsItemBase()
2730 {
2731 return true;
2732 }
2733
2734 // Checks if item is of questioned kind
2735 override bool KindOf(string tag)
2736 {
2737 bool found = false;
2738 string item_name = this.GetType();
2739 ref TStringArray item_tag_array = new TStringArray;
2740 g_Game.ConfigGetTextArray("cfgVehicles " + item_name + " itemInfo", item_tag_array);
2741
2742 int array_size = item_tag_array.Count();
2743 for (int i = 0; i < array_size; i++)
2744 {
2745 if (item_tag_array.Get(i) == tag)
2746 {
2747 found = true;
2748 break;
2749 }
2750 }
2751 return found;
2752 }
2753
2754
2755 override void OnRPC(PlayerIdentity sender, int rpc_type,ParamsReadContext ctx)
2756 {
2757 //Debug.Log("OnRPC called");
2758 super.OnRPC(sender, rpc_type,ctx);
2759
2760 //Play soundset for attachment locking (ActionLockAttachment.c)
2761 switch (rpc_type)
2762 {
2763 #ifndef SERVER
2764 #ifndef NO_GUI
2765 case ERPCs.RPC_SOUND_LOCK_ATTACH:
2766 {
2767 Param2<bool, string> p = new Param2<bool, string>(false, "");
2768
2769 if (!ctx.Read(p))
2770 return;
2771
2772 bool play = p.param1;
2773 string soundSet = p.param2;
2774
2775 if (play)
2776 {
2777 if (m_LockingSound)
2778 {
2779 if (!m_LockingSound.IsSoundPlaying())
2780 {
2781 m_LockingSound = SEffectManager.PlaySound(soundSet, GetPosition(), 0, 0, true);
2782 }
2783 }
2784 else
2785 {
2786 m_LockingSound = SEffectManager.PlaySound(soundSet, GetPosition(), 0, 0, true);
2787 }
2788 }
2789 else
2790 {
2792 }
2793
2794 break;
2795 }
2796 case ERPCs.RPC_ITEM_SOUND_PLAY:
2797 {
2798 int count;
2799 if (!ctx.Read(count))
2800 return;
2801
2802 for (int i = 0; i < count; i++)
2803 {
2804 int soundIdPlay, slotIdPlay;
2805 if (!ctx.Read(soundIdPlay))
2806 return;
2807
2808 if (!ctx.Read(slotIdPlay))
2809 return;
2810
2811 if (m_ItemSoundHandler && soundIdPlay != 0)
2812 m_ItemSoundHandler.PlayItemSoundClient(soundIdPlay, slotIdPlay);
2813 }
2814 break;
2815 }
2816 case ERPCs.RPC_ITEM_SOUND_STOP:
2817 {
2818 int soundIdStop;
2819 if (!ctx.Read(soundIdStop))
2820 return;
2821
2822 if (m_ItemSoundHandler && soundIdStop != 0)
2823 m_ItemSoundHandler.StopItemSoundClient(soundIdStop);
2824 break;
2825 }
2826 #endif
2827 #endif
2828
2829 }
2830
2831 if (GetWrittenNoteData())
2832 {
2833 GetWrittenNoteData().OnRPC(sender, rpc_type,ctx);
2834 }
2835 }
2836
2837 //-----------------------------
2838 // VARIABLE MANIPULATION SYSTEM
2839 //-----------------------------
2840 int NameToID(string name)
2841 {
2842 PluginVariables plugin = PluginVariables.Cast(GetPlugin(PluginVariables));
2843 return plugin.GetID(name);
2844 }
2845
2846 string IDToName(int id)
2847 {
2848 PluginVariables plugin = PluginVariables.Cast(GetPlugin(PluginVariables));
2849 return plugin.GetName(id);
2850 }
2851
2853 void OnSyncVariables(ParamsReadContext ctx)//with ID optimization
2854 {
2855 //Debug.Log("OnSyncVariables called for item: "+ ToString(this.GetType()),"varSync");
2856 //read the flags
2857 int varFlags;
2858 if (!ctx.Read(varFlags))
2859 return;
2860
2861 if (varFlags & ItemVariableFlags.FLOAT)
2862 {
2863 ReadVarsFromCTX(ctx);
2864 }
2865 }
2866
2867 override void SerializeNumericalVars(array<float> floats_out)
2868 {
2869 //some variables handled on EntityAI level already!
2870 super.SerializeNumericalVars(floats_out);
2871
2872 // the order of serialization must be the same as the order of de-serialization
2873 //--------------------------------------------
2874 if (IsVariableSet(VARIABLE_QUANTITY))
2875 {
2876 floats_out.Insert(m_VarQuantity);
2877 }
2878 //--------------------------------------------
2879 if (IsVariableSet(VARIABLE_WET))
2880 {
2881 floats_out.Insert(m_VarWet);
2882 }
2883 //--------------------------------------------
2884 if (IsVariableSet(VARIABLE_LIQUIDTYPE))
2885 {
2886 floats_out.Insert(m_VarLiquidType);
2887 }
2888 //--------------------------------------------
2889 if (IsVariableSet(VARIABLE_COLOR))
2890 {
2891 floats_out.Insert(m_ColorComponentR);
2892 floats_out.Insert(m_ColorComponentG);
2893 floats_out.Insert(m_ColorComponentB);
2894 floats_out.Insert(m_ColorComponentA);
2895 }
2896 //--------------------------------------------
2897 if (IsVariableSet(VARIABLE_CLEANNESS))
2898 {
2899 floats_out.Insert(m_Cleanness);
2900 }
2901 }
2902
2904 {
2905 //some variables handled on EntityAI level already!
2906 super.DeSerializeNumericalVars(floats);
2907
2908 // the order of serialization must be the same as the order of de-serialization
2909 int index = 0;
2910 int mask = Math.Round(floats.Get(index));
2911
2912 index++;
2913 //--------------------------------------------
2914 if (mask & VARIABLE_QUANTITY)
2915 {
2916 if (m_IsStoreLoad)
2917 {
2918 SetStoreLoadedQuantity(floats.Get(index));
2919 }
2920 else
2921 {
2922 float quantity = floats.Get(index);
2923 SetQuantity(quantity, true, false, false, false);
2924 }
2925 index++;
2926 }
2927 //--------------------------------------------
2928 if (mask & VARIABLE_WET)
2929 {
2930 float wet = floats.Get(index);
2931 SetWet(wet);
2932 index++;
2933 }
2934 //--------------------------------------------
2935 if (mask & VARIABLE_LIQUIDTYPE)
2936 {
2937 int liquidtype = Math.Round(floats.Get(index));
2938 SetLiquidType(liquidtype);
2939 index++;
2940 }
2941 //--------------------------------------------
2942 if (mask & VARIABLE_COLOR)
2943 {
2944 m_ColorComponentR = Math.Round(floats.Get(index));
2945 index++;
2946 m_ColorComponentG = Math.Round(floats.Get(index));
2947 index++;
2948 m_ColorComponentB = Math.Round(floats.Get(index));
2949 index++;
2950 m_ColorComponentA = Math.Round(floats.Get(index));
2951 index++;
2952 }
2953 //--------------------------------------------
2954 if (mask & VARIABLE_CLEANNESS)
2955 {
2956 int cleanness = Math.Round(floats.Get(index));
2957 SetCleanness(cleanness);
2958 index++;
2959 }
2960 }
2961
2963 {
2964 super.WriteVarsToCTX(ctx);
2965
2966 //--------------------------------------------
2967 if (IsVariableSet(VARIABLE_QUANTITY))
2968 {
2969 ctx.Write(GetQuantity());
2970 }
2971 //--------------------------------------------
2972 if (IsVariableSet(VARIABLE_WET))
2973 {
2974 ctx.Write(GetWet());
2975 }
2976 //--------------------------------------------
2977 if (IsVariableSet(VARIABLE_LIQUIDTYPE))
2978 {
2979 ctx.Write(GetLiquidType());
2980 }
2981 //--------------------------------------------
2982 if (IsVariableSet(VARIABLE_COLOR))
2983 {
2984 int r,g,b,a;
2985 GetColor(r,g,b,a);
2986 ctx.Write(r);
2987 ctx.Write(g);
2988 ctx.Write(b);
2989 ctx.Write(a);
2990 }
2991 //--------------------------------------------
2992 if (IsVariableSet(VARIABLE_CLEANNESS))
2993 {
2994 ctx.Write(GetCleanness());
2995 }
2996 }
2997
2998 override bool ReadVarsFromCTX(ParamsReadContext ctx, int version = -1)//with ID optimization
2999 {
3000 if (!super.ReadVarsFromCTX(ctx,version))
3001 return false;
3002
3003 int intValue;
3004 float value;
3005
3006 if (version < 140)
3007 {
3008 if (!ctx.Read(intValue))
3009 return false;
3010
3011 m_VariablesMask = intValue;
3012 }
3013
3014 if (m_VariablesMask & VARIABLE_QUANTITY)
3015 {
3016 if (!ctx.Read(value))
3017 return false;
3018
3019 if (IsStoreLoad())
3020 {
3022 }
3023 else
3024 {
3025 SetQuantity(value, true, false, false, false);
3026 }
3027 }
3028 //--------------------------------------------
3029 if (version < 140)
3030 {
3031 if (m_VariablesMask & VARIABLE_TEMPERATURE)
3032 {
3033 if (!ctx.Read(value))
3034 return false;
3035 SetTemperatureDirect(value);
3036 }
3037 }
3038 //--------------------------------------------
3039 if (m_VariablesMask & VARIABLE_WET)
3040 {
3041 if (!ctx.Read(value))
3042 return false;
3043 SetWet(value);
3044 }
3045 //--------------------------------------------
3046 if (m_VariablesMask & VARIABLE_LIQUIDTYPE)
3047 {
3048 if (!ctx.Read(intValue))
3049 return false;
3050 SetLiquidType(intValue);
3051 }
3052 //--------------------------------------------
3053 if (m_VariablesMask & VARIABLE_COLOR)
3054 {
3055 int r,g,b,a;
3056 if (!ctx.Read(r))
3057 return false;
3058 if (!ctx.Read(g))
3059 return false;
3060 if (!ctx.Read(b))
3061 return false;
3062 if (!ctx.Read(a))
3063 return false;
3064
3065 SetColor(r,g,b,a);
3066 }
3067 //--------------------------------------------
3068 if (m_VariablesMask & VARIABLE_CLEANNESS)
3069 {
3070 if (!ctx.Read(intValue))
3071 return false;
3072 SetCleanness(intValue);
3073 }
3074 //--------------------------------------------
3075 if (version >= 138 && version < 140)
3076 {
3077 if (m_VariablesMask & VARIABLE_TEMPERATURE)
3078 {
3079 if (!ctx.Read(intValue))
3080 return false;
3081 SetFrozen(intValue);
3082 }
3083 }
3084
3085 return true;
3086 }
3087
3088 //----------------------------------------------------------------
3089 override bool OnStoreLoad(ParamsReadContext ctx, int version)
3090 {
3091 m_IsStoreLoad = true;
3093 {
3094 m_FixDamageSystemInit = true;
3095 }
3096
3097 if (!super.OnStoreLoad(ctx, version))
3098 {
3099 m_IsStoreLoad = false;
3100 return false;
3101 }
3102
3103 if (version >= 114)
3104 {
3105 bool hasQuickBarIndexSaved;
3106
3107 if (!ctx.Read(hasQuickBarIndexSaved))
3108 {
3109 m_IsStoreLoad = false;
3110 return false;
3111 }
3112
3113 if (hasQuickBarIndexSaved)
3114 {
3115 int itmQBIndex;
3116
3117 //Load quickbar item bind
3118 if (!ctx.Read(itmQBIndex))
3119 {
3120 m_IsStoreLoad = false;
3121 return false;
3122 }
3123
3124 PlayerBase parentPlayer = PlayerBase.Cast(GetHierarchyRootPlayer());
3125 if (itmQBIndex != -1 && parentPlayer)
3126 parentPlayer.SetLoadedQuickBarItemBind(this, itmQBIndex);
3127 }
3128 }
3129 else
3130 {
3131 // Backup of how it used to be
3132 PlayerBase player;
3133 int itemQBIndex;
3134 if (version == int.MAX)
3135 {
3136 if (!ctx.Read(itemQBIndex))
3137 {
3138 m_IsStoreLoad = false;
3139 return false;
3140 }
3141 }
3142 else if (Class.CastTo(player, GetHierarchyRootPlayer()))
3143 {
3144 //Load quickbar item bind
3145 if (!ctx.Read(itemQBIndex))
3146 {
3147 m_IsStoreLoad = false;
3148 return false;
3149 }
3150 if (itemQBIndex != -1 && player)
3151 player.SetLoadedQuickBarItemBind(this,itemQBIndex);
3152 }
3153 }
3154
3155 if (version < 140)
3156 {
3157 // variable management system
3158 if (!LoadVariables(ctx, version))
3159 {
3160 m_IsStoreLoad = false;
3161 return false;
3162 }
3163 }
3164
3165 //agent trasmission system
3166 if (!LoadAgents(ctx, version))
3167 {
3168 m_IsStoreLoad = false;
3169 return false;
3170 }
3171 if (version >= 132)
3172 {
3174 if (raib)
3175 {
3176 if (!raib.OnStoreLoad(ctx,version))
3177 {
3178 m_IsStoreLoad = false;
3179 return false;
3180 }
3181 }
3182 }
3183
3184 m_IsStoreLoad = false;
3185 return true;
3186 }
3187
3188 //----------------------------------------------------------------
3189
3191 {
3192 super.OnStoreSave(ctx);
3193
3194 PlayerBase player;
3195 if (PlayerBase.CastTo(player,GetHierarchyRootPlayer()))
3196 {
3197 ctx.Write(true); // Keep track of if we should actually read this in or not
3198 //Save quickbar item bind
3199 int itemQBIndex = -1;
3200 itemQBIndex = player.FindQuickBarEntityIndex(this);
3201 ctx.Write(itemQBIndex);
3202 }
3203 else
3204 {
3205 ctx.Write(false); // Keep track of if we should actually read this in or not
3206 }
3207
3208 SaveAgents(ctx);//agent trasmission system
3209
3211 if (raib)
3212 {
3213 raib.OnStoreSave(ctx);
3214 }
3215 }
3216 //----------------------------------------------------------------
3217
3218 override void AfterStoreLoad()
3219 {
3220 super.AfterStoreLoad();
3221
3223 {
3225 }
3226
3227 if (GetStoreLoadedQuantity() != float.LOWEST)
3228 {
3230 SetStoreLoadedQuantity(float.LOWEST);//IMPORTANT to do this !! we use 'm_StoreLoadedQuantity' inside SetQuantity to distinguish between initial quantity setting and the consequent(normal gameplay) calls
3231 }
3232 }
3233
3234 override void EEOnAfterLoad()
3235 {
3236 super.EEOnAfterLoad();
3237
3239 {
3240 m_FixDamageSystemInit = false;
3241 }
3242
3245 }
3246
3248 {
3249 return false;
3250 }
3251
3252
3253 //----------------------------------------------------------------
3255 {
3256 if (m_Initialized)
3257 {
3258 #ifdef PLATFORM_CONSOLE
3259 //bruteforce it is
3260 if (IsSplitable())
3261 {
3262 UIScriptedMenu menu = g_Game.GetUIManager().FindMenu(MENU_INVENTORY);
3263 if (menu)
3264 {
3265 menu.Refresh();
3266 }
3267 }
3268 #endif
3269 }
3270
3272 {
3273 PlayImpactSound(ItemBaseType.Cast(GetEntityType()).m_ConfigWeight, m_ImpactSpeed, m_ImpactSoundSurfaceHash);
3274 m_WantPlayImpactSound = false;
3275 }
3276
3278 {
3279 SetWeightDirty();
3281 }
3282 if (m_VarWet != m_VarWetPrev)
3283 {
3286 }
3287
3288 super.OnVariablesSynchronized();
3289 }
3290
3293 protected void LegacyItemSoundSync()
3294 {
3295 if (m_SoundSyncPlay != 0)
3296 {
3299
3300 m_SoundSyncPlay = 0;
3302 }
3303
3304 if (m_SoundSyncStop != 0)
3305 {
3307 m_ItemSoundHandler.StopItemSoundClient(m_SoundSyncStop);
3308 m_SoundSyncStop = 0;
3309 }
3310 }
3311
3312 //------------------------- Quantity
3313 //----------------------------------------------------------------
3315 override bool SetQuantity(float value, bool destroy_config = true, bool destroy_forced = false, bool allow_client = false, bool clamp_to_stack_max = true)
3316 {
3317 if (!IsServerCheck(allow_client))
3318 return false;
3319
3320 if (!HasQuantity())
3321 return false;
3322
3323 float min = GetQuantityMin();
3324 float max = GetQuantityMax();
3325
3326 if (value <= (min + 0.001))
3327 value = min;
3328
3329 if (value == min)
3330 {
3331 if (destroy_config)
3332 {
3333 bool dstr = ConfigGetBool("varQuantityDestroyOnMin");
3334 if (dstr)
3335 {
3336 m_VarQuantity = Math.Clamp(value, min, max);
3337 this.Delete();
3338 return true;
3339 }
3340 }
3341 else if (destroy_forced)
3342 {
3343 m_VarQuantity = Math.Clamp(value, min, max);
3344 this.Delete();
3345 return true;
3346 }
3347 // we get here if destroy_config IS true AND dstr(config destroy param) IS false;
3348 RemoveAllAgents();//we remove all agents when we got to the min value, but the item is not getting deleted
3349 }
3350
3351 float delta = m_VarQuantity;
3352 m_VarQuantity = Math.Clamp(value, min, max);
3353
3354 EntityAI parent = GetHierarchyRoot();
3356 GameInventory gameInventory = GetInventory();
3357 if (gameInventory)
3358 {
3359 gameInventory.GetCurrentInventoryLocation(iLoc);
3360 if (iLoc && iLoc.IsValid() && delta != m_VarQuantity)
3361 {
3362 int iLocSlot = iLoc.GetSlot();
3363 if (delta < m_VarQuantity && iLoc.GetType() != InventoryLocationType.GROUND)
3364 {
3365 StartItemSoundServer(SoundConstants.ITEM_ATTACH, iLocSlot);
3366 }
3367 if (delta > m_VarQuantity && m_VarQuantity != 0 && !IsPrepareToDelete() && iLoc.GetType() == InventoryLocationType.ATTACHMENT)
3368 {
3369 StartItemSoundServer(SoundConstants.ITEM_DETACH, iLocSlot);
3370 }
3371 }
3372 }
3373
3374 if (GetStoreLoadedQuantity() == float.LOWEST)//any other value means we are setting quantity from storage
3375 {
3376 delta = m_VarQuantity - delta;
3377
3378 if (delta)
3379 OnQuantityChanged(delta);
3380 }
3381
3382 SetVariableMask(VARIABLE_QUANTITY);
3383
3384 return false;
3385 }
3386
3387 //----------------------------------------------------------------
3389 bool AddQuantity(float value, bool destroy_config = true, bool destroy_forced = false)
3390 {
3391 return SetQuantity(GetQuantity() + value, destroy_config, destroy_forced);
3392 }
3393 //----------------------------------------------------------------
3395 {
3396 float max = GetQuantityMax();
3397 SetQuantity(max);
3398 }
3399
3400 override void SetQuantityToMinimum()
3401 {
3402 float min = GetQuantityMin();
3403 SetQuantity(min);
3404 }
3405 //----------------------------------------------------------------
3407 override void SetQuantityNormalized(float value, bool destroy_config = true, bool destroy_forced = false)
3408 {
3409 float value_clamped = Math.Clamp(value, 0, 1);//just to make sure
3410 int result = Math.Round(Math.Lerp(GetQuantityMin(), GetQuantityMax(), value_clamped));
3411 SetQuantity(result, destroy_config, destroy_forced);
3412 }
3413
3414 //----------------------------------------------------------------
3416 override float GetQuantityNormalized()
3417 {
3419 }
3420
3422 {
3423 return GetQuantityNormalized();
3424 }
3425
3426 /*void SetAmmoNormalized(float value)
3427 {
3428 float value_clamped = Math.Clamp(value, 0, 1);
3429 Magazine this_mag = Magazine.Cast(this);
3430 int max_rounds = this_mag.GetAmmoMax();
3431 int result = value * max_rounds;//can the rounded if higher precision is required
3432 this_mag.SetAmmoCount(result);
3433 }*/
3434 //----------------------------------------------------------------
3435 override int GetQuantityMax()
3436 {
3437 int slot = -1;
3438 GameInventory inventory = GetInventory();
3439 if (inventory)
3440 {
3442 inventory.GetCurrentInventoryLocation(il);
3443 slot = il.GetSlot();
3444 }
3445
3446 return GetTargetQuantityMax(slot);
3447 }
3448
3449 override int GetTargetQuantityMax(int attSlotID = -1)
3450 {
3451 float quantityMax = 0;
3452
3453 ItemBaseType itemBaseType = ItemBaseType.Cast(GetEntityType());
3454
3455 if (IsSplitable()) //only stackable/splitable items can check for stack size
3456 {
3457 if (attSlotID != -1)
3459
3460 if (quantityMax <= 0)
3461 quantityMax = itemBaseType.m_VarStackMax;
3462 }
3463
3464 if (quantityMax <= 0)
3465 quantityMax = itemBaseType.m_VarQuantityMax;
3466
3467 return quantityMax;
3468 }
3469 //----------------------------------------------------------------
3470 override int GetQuantityMin()
3471 {
3472 return ItemBaseType.Cast(GetEntityType()).m_VarQuantityMin;
3473 }
3474 //----------------------------------------------------------------
3476 {
3477 return ItemBaseType.Cast(GetEntityType()).m_VarQuantityInit;
3478 }
3479
3480 //----------------------------------------------------------------
3481 override bool HasQuantity()
3482 {
3483 return !(GetQuantityMax() - GetQuantityMin() == 0);
3484 }
3485
3486 override float GetQuantity()
3487 {
3488 return m_VarQuantity;
3489 }
3490
3492 {
3493 return GetQuantity() >= GetQuantityMax();
3494 }
3495
3496 //Calculates weight of single item without attachments and cargo
3498 {
3499 //this needs to be first stored inside local variables, when returned directly during inside return call, the result is completely different due to enforce script bug
3500 float weightEx = GetWeightEx();//overall weight of the item
3501 float special = GetInventoryAndCargoWeight();//cargo and attachment weight
3502 return weightEx - special;
3503 }
3504
3505 // Obsolete, use GetSingleInventoryItemWeightEx() instead
3510
3511 override protected float GetWeightSpecialized(bool forceRecalc = false)
3512 {
3513 if (IsSplitable()) //quantity determines size of the stack
3514 {
3515 #ifdef DEVELOPER
3516 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
3517 {
3518 WeightDebugData data1 = WeightDebug.GetWeightDebug(this);
3519 data1.SetCalcDetails("TIB1: " + GetConfigWeightModifiedDebugText() +" * " + GetQuantity()+"(quantity)");
3520 }
3521 #endif
3522
3523 return GetQuantity() * GetConfigWeightModified();
3524 }
3525 else if (HasEnergyManager())// items with energy manager
3526 {
3527 #ifdef DEVELOPER
3528 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
3529 {
3530 WeightDebugData data2 = WeightDebug.GetWeightDebug(this);
3531 data2.SetCalcDetails("TIB2: "+super.GetWeightSpecialized(forceRecalc)+"(contents weight) + " + GetConfigWeightModifiedDebugText() +" + " + GetCompEM().GetEnergy()+"(energy) * " + ConfigGetFloat("weightPerQuantityUnit") +"(weightPerQuantityUnit)");
3532 }
3533 #endif
3534 return super.GetWeightSpecialized(forceRecalc) + (GetCompEM().GetEnergy() * ConfigGetFloat("weightPerQuantityUnit")) + GetConfigWeightModified();
3535 }
3536 else//everything else
3537 {
3538 #ifdef DEVELOPER
3539 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
3540 {
3541 WeightDebugData data3 = WeightDebug.GetWeightDebug(this);
3542 data3.SetCalcDetails("TIB3: "+super.GetWeightSpecialized(forceRecalc)+"(contents weight) + " + GetConfigWeightModifiedDebugText() +" + " + GetQuantity()+"(quantity) * " + ConfigGetFloat("weightPerQuantityUnit") +"(weightPerQuantityUnit))");
3543 }
3544 #endif
3545 return super.GetWeightSpecialized(forceRecalc) + (GetQuantity() * ConfigGetFloat("weightPerQuantityUnit")) + GetConfigWeightModified();
3546 }
3547 }
3548
3551 {
3552 int item_count = 0;
3553 ItemBase item;
3554
3555 GameInventory inventory = GetInventory();
3556 CargoBase cargo = inventory.GetCargo();
3557 if (cargo != NULL)
3558 {
3559 item_count = cargo.GetItemCount();
3560 }
3561
3562 int nAttachments = inventory.AttachmentCount();
3563 for (int i = 0; i < nAttachments; ++i)
3564 {
3565 Class.CastTo(item, inventory.GetAttachmentFromIndex(i));
3566 if (item)
3567 item_count += item.GetNumberOfItems();
3568 }
3569 return item_count;
3570 }
3571
3573 float GetUnitWeight(bool include_wetness = true)
3574 {
3575 float weight = 0;
3576 float wetness = 1;
3577 if (include_wetness)
3578 wetness += GetWet();
3579 if (IsSplitable()) //quantity determines size of the stack
3580 {
3581 weight = wetness * ItemBaseType.Cast(GetEntityType()).m_ConfigWeight;
3582 }
3583 else if (IsLiquidContainer()) //is a liquid container, default liquid weight is set to 1. May revisit later?
3584 {
3585 weight = 1;
3586 }
3587 return weight;
3588 }
3589
3590 //-----------------------------------------------------------------
3591
3592 override void ClearInventory()
3593 {
3594 GameInventory inventory = GetInventory();
3595 if ((g_Game.IsServer() || !g_Game.IsMultiplayer()) && inventory)
3596 {
3597 array<EntityAI> items = new array<EntityAI>;
3598 inventory.EnumerateInventory(InventoryTraversalType.INORDER, items);
3599 for (int i = 0; i < items.Count(); ++i)
3600 {
3601 ItemBase item = ItemBase.Cast(items.Get(i));
3602 if (item)
3603 {
3604 g_Game.ObjectDelete(item);
3605 }
3606 }
3607 }
3608 }
3609
3610 //------------------------- Energy
3611
3612 //----------------------------------------------------------------
3614 {
3615 float energy = 0;
3616 if (HasEnergyManager())
3617 {
3618 energy = GetCompEM().GetEnergy();
3619 }
3620 return energy;
3621 }
3622
3623
3624 override void OnEnergyConsumed()
3625 {
3626 super.OnEnergyConsumed();
3627
3629 }
3630
3631 override void OnEnergyAdded()
3632 {
3633 super.OnEnergyAdded();
3634
3636 }
3637
3638 // Converts energy (from Energy Manager) to quantity, if enabled.
3640 {
3641 if (!HasQuantity())
3642 return;
3643
3644 ComponentEnergyManager compEM = GetCompEM();
3645 if ((g_Game.IsServer() || !g_Game.IsMultiplayer()) && compEM && compEM.HasConversionOfEnergyToQuantity())
3646 {
3647 float energy0To1 = compEM.GetEnergy0To1();
3648 SetQuantityNormalized(energy0To1);
3649 }
3650 }
3651
3652 //----------------------------------------------------------------
3654 {
3655 return ItemBaseType.Cast(GetEntityType()).m_HeatIsolation;
3656 }
3657
3658 float GetDryingIncrement(EEnvironmentDryingCategories pCategory)
3659 {
3660 return ItemBaseType.Cast(GetEntityType()).m_DryingIncrements[pCategory];
3661 }
3662
3663 float GetSoakingIncrement(EEnvironmentSoakingCategories pCategory)
3664 {
3665 return ItemBaseType.Cast(GetEntityType()).m_SoakingIncrements[pCategory];
3666 }
3667
3668 [Obsolete("1.30: replaced by GetDryingIncrement taking enum/int arguments")]
3669 float GetDryingIncrement(string pIncrementName)
3670 {
3671 string paramPath = string.Format("CfgVehicles %1 EnvironmentWetnessIncrements Drying %2", GetType(), pIncrementName);
3672 if (g_Game.ConfigIsExisting(paramPath))
3673 return g_Game.ConfigGetFloat(paramPath);
3674
3675 return 0.0;
3676 }
3677
3678 [Obsolete("1.30: replaced by GetSoakingIncrement taking enum/int arguments")]
3679 float GetSoakingIncrement(string pIncrementName)
3680 {
3681 string paramPath = string.Format("CfgVehicles %1 EnvironmentWetnessIncrements Soaking %2", GetType(), pIncrementName);
3682 if (g_Game.ConfigIsExisting(paramPath))
3683 return g_Game.ConfigGetFloat(paramPath);
3684
3685 return 0.0;
3686 }
3687 //----------------------------------------------------------------
3688 override void SetWet(float value, bool allow_client = false)
3689 {
3690 if (!IsServerCheck(allow_client))
3691 return;
3692
3693 float min = GetWetMin();
3694 float max = GetWetMax();
3695
3696 float previousValue = m_VarWet;
3697
3698 m_VarWet = Math.Clamp(value, min, max);
3699
3700 if (previousValue != m_VarWet)
3701 {
3702 SetVariableMask(VARIABLE_WET);
3703 OnWetChanged(m_VarWet, previousValue);
3704 }
3705 }
3706 //----------------------------------------------------------------
3707 override void AddWet(float value)
3708 {
3709 SetWet(GetWet() + value);
3710 }
3711 //----------------------------------------------------------------
3712 override void SetWetMax()
3713 {
3714 SetWet(ItemBaseType.Cast(GetEntityType()).m_VarWetMax);
3715 }
3716 //----------------------------------------------------------------
3717 override float GetWet()
3718 {
3719 return m_VarWet;
3720 }
3721 //----------------------------------------------------------------
3722 override float GetWetMax()
3723 {
3724 return ItemBaseType.Cast(GetEntityType()).m_VarWetMax;
3725 }
3726 //----------------------------------------------------------------
3727 override float GetWetMin()
3728 {
3729 return ItemBaseType.Cast(GetEntityType()).m_VarWetMin;
3730 }
3731 //----------------------------------------------------------------
3732 override float GetWetInit()
3733 {
3734 return ItemBaseType.Cast(GetEntityType()).m_VarWetInit;
3735 }
3736 //----------------------------------------------------------------
3737 override void OnWetChanged(float newVal, float oldVal)
3738 {
3739 EWetnessLevel newLevel = GetWetLevelInternal(newVal);
3740 EWetnessLevel oldLevel = GetWetLevelInternal(oldVal);
3741 if (newLevel != oldLevel)
3742 {
3743 OnWetLevelChanged(newLevel,oldLevel);
3744 }
3745 }
3746
3747 override void OnWetLevelChanged(EWetnessLevel newLevel, EWetnessLevel oldLevel)
3748 {
3749 SetWeightDirty();
3750 }
3751
3753 {
3754 return GetWetLevelInternal(m_VarWet);
3755 }
3756
3757 //----------------------------------------------------------------
3758
3759 override void SetStoreLoad(bool value)
3760 {
3761 m_IsStoreLoad = value;
3762 }
3763
3764 override bool IsStoreLoad()
3765 {
3766 return m_IsStoreLoad;
3767 }
3768
3769 override void SetStoreLoadedQuantity(float value)
3770 {
3771 m_StoreLoadedQuantity = value;
3772 }
3773
3774 override float GetStoreLoadedQuantity()
3775 {
3776 return m_StoreLoadedQuantity;
3777 }
3778
3779 //----------------------------------------------------------------
3780
3782 {
3783 return ItemBaseType.Cast(GetEntityType()).m_ItemModelLength;
3784 }
3785
3787 {
3788 return ItemBaseType.Cast(GetEntityType()).m_ItemAttachOffset;
3789 }
3790
3791 override void SetCleanness(int value, bool allow_client = false)
3792 {
3793 if (!IsServerCheck(allow_client))
3794 return;
3795
3796 int previousValue = m_Cleanness;
3797
3798 ItemBaseType itemBaseType = ItemBaseType.Cast(GetEntityType());
3799 m_Cleanness = Math.Clamp(value, itemBaseType.m_CleannessMin, itemBaseType.m_CleannessMax);
3800
3801 if (previousValue != m_Cleanness)
3802 SetVariableMask(VARIABLE_CLEANNESS);
3803 }
3804
3805 override int GetCleanness()
3806 {
3807 return m_Cleanness;
3808 }
3809
3811 {
3812 return true;
3813 }
3814
3815 //----------------------------------------------------------------
3816 // ATTACHMENT LOCKING
3817 // Getters relevant to generic ActionLockAttachment
3819 {
3820 return ItemBaseType.Cast(GetEntityType()).m_LockType;
3821 }
3822
3824 {
3825 return ItemBaseType.Cast(GetEntityType()).m_LockSoundSet;
3826 }
3827
3828 //----------------------------------------------------------------
3829 //------------------------- Color
3830 // sets items color variable given color components
3831 override void SetColor(int r, int g, int b, int a)
3832 {
3837 SetVariableMask(VARIABLE_COLOR);
3838 }
3839
3840 override void GetColor(out int r,out int g,out int b,out int a)
3841 {
3846 }
3847
3849 {
3850 return IsVariableSet(VARIABLE_COLOR);
3851 }
3852
3855 {
3856 int r,g,b,a;
3857 GetColor(r,g,b,a);
3858 r = r/255;
3859 g = g/255;
3860 b = b/255;
3861 a = a/255;
3862 return MiscGameplayFunctions.GetColorString(r, g, b, a);
3863 }
3864 //----------------------------------------------------------------
3865 //------------------------- LiquidType
3866
3867 override void SetLiquidType(int value, bool allow_client = false)
3868 {
3869 if (!IsServerCheck(allow_client))
3870 return;
3871
3872 int old = m_VarLiquidType;
3873 m_VarLiquidType = value;
3874 OnLiquidTypeChanged(old,value);
3875 SetVariableMask(VARIABLE_LIQUIDTYPE);
3876 }
3877
3879 {
3880 return ItemBaseType.Cast(GetEntityType()).m_VarLiquidTypeInit;
3881 }
3882
3883 override int GetLiquidType()
3884 {
3885 return m_VarLiquidType;
3886 }
3887
3888 protected void OnLiquidTypeChanged(int oldType, int newType)
3889 {
3890 if (newType == LIQUID_NONE && GetIsFrozen())
3891 SetFrozen(false);
3892 }
3893
3896 {
3897 player.SetEnableQuickBarEntityShortcut(this,!GetHierarchyParent() || GetHierarchyParent().GetInventory().AreChildrenAccessible());
3898 }
3899
3900 // -------------------------------------------------------------------------
3902 void OnInventoryEnter(Man player)
3903 {
3904 PlayerBase nplayer;
3905 if (PlayerBase.CastTo(nplayer, player))
3906 {
3907 m_CanPlayImpactSound = true;
3908 nplayer.SetEnableQuickBarEntityShortcut(this,!GetHierarchyParent() || GetHierarchyParent().GetInventory().AreChildrenAccessible());
3909 }
3910 }
3911
3912 // -------------------------------------------------------------------------
3914 void OnInventoryExit(Man player)
3915 {
3916 PlayerBase nplayer;
3917 if (PlayerBase.CastTo(nplayer,player))
3918 {
3919 nplayer.SetEnableQuickBarEntityShortcut(this, false);
3920 }
3921
3922 player.GetHumanInventory().ClearUserReservedLocationForContainer(this);
3923
3924 if (HasEnergyManager())
3925 {
3926 GetCompEM().UpdatePlugState(); // Unplug the el. device if it's necesarry.
3927 }
3928 }
3929
3930 // ADVANCED PLACEMENT EVENTS
3931 override void OnPlacementStarted(Man player)
3932 {
3933 super.OnPlacementStarted(player);
3934
3935 SetTakeable(false);
3936 }
3937
3938 override void OnPlacementComplete(Man player, vector position = "0 0 0", vector orientation = "0 0 0")
3939 {
3940 if (m_AdminLog)
3941 {
3942 m_AdminLog.OnPlacementComplete(player, this);
3943 }
3944
3945 super.OnPlacementComplete(player, position, orientation);
3946 }
3947
3948 //-----------------------------
3949 // AGENT SYSTEM
3950 //-----------------------------
3951 //--------------------------------------------------------------------------
3952 bool ContainsAgent(int agent_id)
3953 {
3954 if (agent_id & m_AttachedAgents)
3955 {
3956 return true;
3957 }
3958 else
3959 {
3960 return false;
3961 }
3962 }
3963
3964 //--------------------------------------------------------------------------
3965 override void RemoveAgent(int agent_id)
3966 {
3967 if (ContainsAgent(agent_id))
3968 {
3969 m_AttachedAgents = ~agent_id & m_AttachedAgents;
3970 }
3971 }
3972
3973 //--------------------------------------------------------------------------
3974 override void RemoveAllAgents()
3975 {
3976 m_AttachedAgents = 0;
3977 }
3978 //--------------------------------------------------------------------------
3979 override void RemoveAllAgentsExcept(int agent_to_keep)
3980 {
3981 m_AttachedAgents = m_AttachedAgents & agent_to_keep;
3982 }
3983 // -------------------------------------------------------------------------
3984 override void InsertAgent(int agent, float count = 1)
3985 {
3986 if (count < 1)
3987 return;
3988 //Debug.Log("Inserting Agent on item: " + agent.ToString() +" count: " + count.ToString());
3990 }
3991
3993 void TransferAgents(int agents)
3994 {
3996 }
3997
3998 // -------------------------------------------------------------------------
3999 override int GetAgents()
4000 {
4001 return m_AttachedAgents;
4002 }
4003 //----------------------------------------------------------------------
4004
4005 /*int GetContaminationType()
4006 {
4007 int contamination_type;
4008
4009 const int CONTAMINATED_MASK = eAgents.CHOLERA | eAgents.INFLUENZA | eAgents.SALMONELLA | eAgents.BRAIN;
4010 const int POISONED_MASK = eAgents.FOOD_POISON | eAgents.CHEMICAL_POISON;
4011 const int NERVE_GAS_MASK = eAgents.CHEMICAL_POISON;
4012 const int DIRTY_MASK = eAgents.WOUND_AGENT;
4013
4014 Edible_Base edible = Edible_Base.Cast(this);
4015 int agents = GetAgents();
4016 if (edible)
4017 {
4018 NutritionalProfile profile = Edible_Base.GetNutritionalProfile(edible);
4019 if (profile)
4020 {
4021 agents = agents | profile.GetAgents();//merge item's agents with nutritional agents
4022 }
4023 }
4024 if (agents & CONTAMINATED_MASK)
4025 {
4026 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_CONTAMINATED;
4027 }
4028 if (agents & POISONED_MASK)
4029 {
4030 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_POISONED;
4031 }
4032 if (agents & NERVE_GAS_MASK)
4033 {
4034 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_NERVE_GAS;
4035 }
4036 if (agents & DIRTY_MASK)
4037 {
4038 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_DIRTY;
4039 }
4040
4041 return agents;
4042 }*/
4043
4044 // -------------------------------------------------------------------------
4045 bool LoadAgents(ParamsReadContext ctx, int version)
4046 {
4047 if (!ctx.Read(m_AttachedAgents))
4048 return false;
4049 return true;
4050 }
4051 // -------------------------------------------------------------------------
4053 {
4054
4056 }
4057 // -------------------------------------------------------------------------
4058
4060 override void CheckForRoofLimited(float timeTresholdMS = 3000)
4061 {
4062 super.CheckForRoofLimited(timeTresholdMS);
4063
4064 float time = g_Game.GetTime();
4065 if ((time - m_PreviousRoofTestTime) >= timeTresholdMS)
4066 {
4067 m_PreviousRoofTestTime = time;
4068 SetRoofAbove(MiscGameplayFunctions.IsUnderRoof(this));
4069 }
4070 }
4071
4072 // returns item's protection level against enviromental hazard, for masks with filters, returns the filters protection for valid filter, otherwise 0
4073 float GetProtectionLevel(int type, bool consider_filter = false, int system = 0)
4074 {
4075 if (IsDamageDestroyed() || (HasQuantity() && GetQuantity() <= 0))
4076 return 0.0;
4077
4078 string subclassPath, entryName;
4079
4080 switch (type)
4081 {
4082 case DEF_BIOLOGICAL:
4083 entryName = "biological";
4084 break;
4085 case DEF_CHEMICAL:
4086 entryName = "chemical";
4087 break;
4089 entryName = "dust_particle_breath";
4090 break;
4092 entryName = "dust_particle_eyes";
4093 break;
4094 default:
4095 entryName = "biological";
4096 break;
4097 }
4098
4099 subclassPath = "CfgVehicles " + this.GetType() + " Protection ";
4100
4101 return g_Game.ConfigGetFloat(subclassPath + entryName);
4102 }
4103
4104
4105
4107 override void EEOnCECreate()
4108 {
4109 if (!IsMagazine())
4111
4113 }
4114
4115
4116 //-------------------------
4117 // OPEN/CLOSE USER ACTIONS
4118 //-------------------------
4120 void Open();
4121 void Close();
4122 bool IsOpen()
4123 {
4124 return true;
4125 }
4126
4127 override bool CanDisplayCargo()
4128 {
4129 return IsOpen();
4130 }
4131
4132
4133 // ------------------------------------------------------------
4134 // CONDITIONS
4135 // ------------------------------------------------------------
4136 override bool CanPutInCargo(EntityAI parent)
4137 {
4138 if (parent)
4139 {
4140 if (parent.IsInherited(DayZInfected))
4141 return true;
4142
4143 if (!parent.IsRuined())
4144 return true;
4145 }
4146
4147 return true;
4148 }
4149
4150 override bool CanPutAsAttachment(EntityAI parent)
4151 {
4152 if (!super.CanPutAsAttachment(parent))
4153 {
4154 return false;
4155 }
4156
4157 if (!IsRuined() && !parent.IsRuined())
4158 {
4159 return true;
4160 }
4161
4162 return false;
4163 }
4164
4166 {
4167 //removed 15.06. coz of loading from storage -> after load items in cargo was lost -> waiting for proper solution
4168 //if (GetHealthLevel() == GameConstants.STATE_RUINED)
4169 // return false;
4170
4171 return super.CanReceiveItemIntoCargo(item);
4172 }
4173
4174 override bool CanReceiveAttachment(EntityAI attachment, int slotId)
4175 {
4176 //removed 15.06. coz of loading from storage -> after load items in cargo was lost -> waiting for proper solution
4177 //if (GetHealthLevel() == GameConstants.STATE_RUINED)
4178 // return false;
4179
4180 GameInventory attachmentInv = attachment.GetInventory();
4181 if (attachmentInv && attachmentInv.GetCargo() && attachmentInv.GetCargo().GetItemCount() > 0)
4182 {
4183 if (GetHierarchyParent() && !GetHierarchyParent().IsInherited(PlayerBase))
4184 return false;
4185 }
4186
4188 attachment.GetInventory().GetCurrentInventoryLocation(loc);
4189 if (loc && loc.IsValid() && !GetInventory().AreChildrenAccessible())
4190 return false;
4191
4192 return super.CanReceiveAttachment(attachment, slotId);
4193 }
4194
4195 override bool CanReleaseAttachment(EntityAI attachment)
4196 {
4197 if (!super.CanReleaseAttachment(attachment))
4198 return false;
4199
4200 return GetInventory().AreChildrenAccessible();
4201 }
4202
4203 /*override bool CanLoadAttachment(EntityAI attachment)
4204 {
4205 //removed 15.06. coz of loading from storage -> after load items in cargo was lost -> waiting for proper solution
4206 //if (GetHealthLevel() == GameConstants.STATE_RUINED)
4207 // return false;
4208
4209 GameInventory attachmentInv = attachment.GetInventory();
4210 if (attachmentInv && attachmentInv.GetCargo() && attachmentInv.GetCargo().GetItemCount() > 0)
4211 {
4212 bool boo = (GetHierarchyParent() && !GetHierarchyParent().IsInherited(PlayerBase));
4213 ErrorEx("CanLoadAttachment | this: " + this + " | attachment: " + attachment + " | boo: " + boo,ErrorExSeverity.INFO);
4214
4215 if (GetHierarchyParent() && !GetHierarchyParent().IsInherited(PlayerBase))
4216 return false;
4217 }
4218
4219 return super.CanLoadAttachment(attachment);
4220 }*/
4221
4222 // Plays muzzle flash particle effects
4223 static void PlayFireParticles(ItemBase weapon, int muzzle_index, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
4224 {
4225 int id = muzzle_owner.GetMuzzleID();
4227
4228 if (WPOF_array)
4229 {
4230 for (int i = 0; i < WPOF_array.Count(); i++)
4231 {
4232 WeaponParticlesOnFire WPOF = WPOF_array.Get(i);
4233
4234 if (WPOF)
4235 {
4236 WPOF.OnActivate(weapon, muzzle_index, ammoType, muzzle_owner, suppressor, config_to_search);
4237 }
4238 }
4239 }
4240 }
4241
4242 // Plays bullet eject particle effects (usually just smoke, the bullet itself is a 3D model and is not part of this function)
4243 static void PlayBulletCasingEjectParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
4244 {
4245 int id = muzzle_owner.GetMuzzleID();
4247
4248 if (WPOBE_array)
4249 {
4250 for (int i = 0; i < WPOBE_array.Count(); i++)
4251 {
4252 WeaponParticlesOnBulletCasingEject WPOBE = WPOBE_array.Get(i);
4253
4254 if (WPOBE)
4255 {
4256 WPOBE.OnActivate(weapon, 0, ammoType, muzzle_owner, suppressor, config_to_search);
4257 }
4258 }
4259 }
4260 }
4261
4262 // Plays all weapon overheating particles
4263 static void PlayOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
4264 {
4265 int id = muzzle_owner.GetMuzzleID();
4266 array<ref WeaponParticlesOnOverheating> WPOOH_array = weapon.m_OnOverheatingEffect.Get(id);
4267
4268 if (WPOOH_array)
4269 {
4270 for (int i = 0; i < WPOOH_array.Count(); i++)
4271 {
4272 WeaponParticlesOnOverheating WPOOH = WPOOH_array.Get(i);
4273
4274 if (WPOOH)
4275 {
4276 WPOOH.OnActivate(weapon, 0, ammoType, muzzle_owner, suppressor, config_to_search);
4277 }
4278 }
4279 }
4280 }
4281
4282 // Updates all weapon overheating particles
4283 static void UpdateOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
4284 {
4285 int id = muzzle_owner.GetMuzzleID();
4286 array<ref WeaponParticlesOnOverheating> WPOOH_array = weapon.m_OnOverheatingEffect.Get(id);
4287
4288 if (WPOOH_array)
4289 {
4290 for (int i = 0; i < WPOOH_array.Count(); i++)
4291 {
4292 WeaponParticlesOnOverheating WPOOH = WPOOH_array.Get(i);
4293
4294 if (WPOOH)
4295 {
4296 WPOOH.OnUpdate(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
4297 }
4298 }
4299 }
4300 }
4301
4302 // Stops overheating particles
4303 static void StopOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
4304 {
4305 int id = muzzle_owner.GetMuzzleID();
4306 array<ref WeaponParticlesOnOverheating> WPOOH_array = weapon.m_OnOverheatingEffect.Get(id);
4307
4308 if (WPOOH_array)
4309 {
4310 for (int i = 0; i < WPOOH_array.Count(); i++)
4311 {
4312 WeaponParticlesOnOverheating WPOOH = WPOOH_array.Get(i);
4313
4314 if (WPOOH)
4315 {
4316 WPOOH.OnDeactivate(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
4317 }
4318 }
4319 }
4320 }
4321
4322 //----------------------------------------------------------------
4323 //Item Behaviour - unified approach
4324 override bool IsHeavyBehaviour()
4325 {
4326 if (ItemBaseType.Cast(GetEntityType()).m_ItemBehaviour == 0)
4327 return true;
4328
4329 return false;
4330 }
4331
4332 override bool IsOneHandedBehaviour()
4333 {
4334 if (ItemBaseType.Cast(GetEntityType()).m_ItemBehaviour == 1)
4335 return true;
4336
4337 return false;
4338 }
4339
4340 override bool IsTwoHandedBehaviour()
4341 {
4342 if (ItemBaseType.Cast(GetEntityType()).m_ItemBehaviour == 2)
4343 return true;
4344
4345 return false;
4346 }
4347
4349 {
4350 return false;
4351 }
4352
4355 {
4357 }
4358
4359
4360 //----------------------------------------------------------------
4361 // Item Targeting (User Actions)
4362 override void SetTakeable(bool pState)
4363 {
4364 m_IsTakeable = pState;
4365 SetSynchDirty();
4366 }
4367
4368 override bool IsTakeable()
4369 {
4370 return m_IsTakeable;
4371 }
4372
4373 // For cases where we want to show object widget which cant be taken to hands
4375 {
4376 return false;
4377 }
4378
4381 {
4382 string att_type = "None";
4383
4384 if (ConfigIsExisting("soundAttType"))
4385 {
4386 att_type = ConfigGetString("soundAttType");
4387 }
4388
4389 m_SoundAttType = att_type;
4390 }
4391
4392 override string GetAttachmentSoundType()
4393 {
4394 return m_SoundAttType;
4395 }
4396
4397 //----------------------------------------------------------------
4398 //SOUNDS - ItemSoundHandler
4399 //----------------------------------------------------------------
4400
4401 string GetPlaceSoundset(); // played when deploy starts
4402 string GetLoopDeploySoundset(); // played when deploy starts and stopped when it finishes
4403 string GetDeploySoundset(); // played when deploy sucessfully finishes
4404 string GetLoopFoldSoundset(); // played when fold starts and stopped when it finishes
4405 string GetFoldSoundset(); // played when fold sucessfully finishes
4406
4414
4415 // override to initialize sounds
4416 protected void InitItemSounds()
4417 {
4418 if (GetPlaceSoundset() == string.Empty && GetDeploySoundset() == string.Empty && GetLoopDeploySoundset() == string.Empty && !GetInventoryItemType().SetDetachSoundEvent() && !GetInventoryItemType().SetAttachSoundEvent())
4419 return;
4420
4422
4423 if (GetPlaceSoundset() != string.Empty)
4424 handler.AddSound(SoundConstants.ITEM_PLACE, GetPlaceSoundset());
4425
4426 if (GetDeploySoundset() != string.Empty)
4427 handler.AddSound(SoundConstants.ITEM_DEPLOY, GetDeploySoundset());
4428
4429 SoundParameters params = new SoundParameters();
4430 params.m_Loop = true;
4431 if (GetLoopDeploySoundset() != string.Empty)
4432 handler.AddSound(SoundConstants.ITEM_DEPLOY_LOOP, GetLoopDeploySoundset(), params);
4433 }
4434
4435 // Start sound using ItemSoundHandler
4436 void StartItemSoundServer(int id, int slotId)
4437 {
4438 if (!GetGame().IsServer() || id <= 0)
4439 return;
4440
4441 if (!m_SoundEventQueue)
4443
4444 m_SoundEventQueue.Insert(new ItemSoundEvent(id, slotId));
4445
4446 // flush once per frame instead of per-insert (batches multiple sounds)
4447 GetGame().GetCallQueue(CALL_CATEGORY_SYSTEM).Remove(FlushItemSoundQueue);
4448 GetGame().GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(FlushItemSoundQueue);
4449 }
4450
4455
4457 {
4458 if (g_Game.IsClient() && m_ItemSoundHandler)
4459 {
4460 m_ItemSoundHandler.PlayItemSoundClient(id, slotId);
4461 }
4462 }
4463
4464 protected void FlushItemSoundQueue()
4465 {
4466 if (!m_SoundEventQueue || m_SoundEventQueue.Count() == 0)
4467 return;
4468
4469 ScriptRPC rpc = new ScriptRPC();
4470 rpc.Write(m_SoundEventQueue.Count());
4471 foreach (ItemSoundEvent ev : m_SoundEventQueue)
4472 {
4473 rpc.Write(ev.m_SoundId);
4474 rpc.Write(ev.m_SlotId);
4475 }
4476 rpc.Send(this, ERPCs.RPC_ITEM_SOUND_PLAY, true);
4477
4478 m_SoundEventQueue.Clear();
4479 }
4480
4484 {
4485 if (!g_Game.IsServer())
4486 return;
4487
4488 m_SoundSyncStop = id;
4489 SetSynchDirty();
4490
4491 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).Remove(ClearStopItemSoundServer); // in case one is queued already
4492 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(ClearStopItemSoundServer, 100);
4493 }
4494
4496 {
4497 if (!g_Game.IsServer())
4498 return;
4499
4500 ScriptRPC rpc = new ScriptRPC();
4501 rpc.Write(id);
4502 rpc.Send(this, ERPCs.RPC_ITEM_SOUND_STOP, true);
4503 }
4504
4506 {
4507 m_SoundSyncStop = 0;
4508 }
4509
4510 void OnApply(PlayerBase player);
4511
4513 {
4514 return 1.0;
4515 };
4516
4517 //returns applicable selection
4519 {
4520 return ItemBaseType.Cast(GetEntityType()).m_HeadHidingSelections;
4521 }
4522
4524 {
4525 return ItemBaseType.Cast(GetEntityType()).m_HideSelectionsBySlot;
4526 }
4527
4529
4531 {
4532 SetDynamicPhysicsLifeTime(0.01);
4533 m_ItemBeingDroppedPhys = false;
4534 }
4535
4537 {
4538 array<string> zone_names = new array<string>;
4539 GetDamageZones(zone_names);
4540 for (int i = 0; i < zone_names.Count(); i++)
4541 {
4542 SetHealthMax(zone_names.Get(i),"Health");
4543 }
4544 SetHealthMax("","Health");
4545 }
4546
4549 {
4550 float global_health = GetHealth01("","Health");
4551 array<string> zones = new array<string>;
4552 GetDamageZones(zones);
4553 //set damage of all zones to match global health level
4554 for (int i = 0; i < zones.Count(); i++)
4555 {
4556 SetHealth01(zones.Get(i),"Health",global_health);
4557 }
4558 }
4559
4561 bool IsCoverFaceForShave(string slot_name)
4562 {
4563 return IsExclusionFlagPresent(PlayerBase.GetFaceCoverageShaveValues());
4564 }
4565
4566 void ProcessItemWetness(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
4567 {
4568 if (!hasRootAsPlayer)
4569 {
4570 ItemBaseType itemBaseType = ItemBaseType.Cast(GetEntityType());
4571 if (refParentIB)
4572 {
4573 // parent is wet
4574 if ((refParentIB.GetWet() >= GameConstants.STATE_SOAKING_WET) && (m_VarWet < ItemBaseType.Cast(GetEntityType()).m_VarWetMax))
4576 // parent has liquid inside
4577 else if ((refParentIB.GetLiquidType() != 0) && (refParentIB.GetQuantity() > 0) && (m_VarWet < ItemBaseType.Cast(GetEntityType()).m_VarWetMax))
4579 // drying
4580 else if (m_VarWet > itemBaseType.m_VarWetMin)
4581 AddWet(-1 * delta * GetDryingIncrement(EEnvironmentDryingCategories.GROUND) * 2);
4582 }
4583 else
4584 {
4585 // drying on ground or inside non-itembase (car, ...)
4586 if (m_VarWet > itemBaseType.m_VarWetMin)
4587 AddWet(-1 * delta * GetDryingIncrement(EEnvironmentDryingCategories.GROUND));
4588 }
4589 }
4590 }
4591
4592 void ProcessItemTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
4593 {
4595 {
4596 float target = g_Game.GetMission().GetWorldData().GetBaseEnvTemperatureAtObject(this);
4597 if (GetTemperature() != target || !IsFreezeThawProgressFinished())
4598 {
4599 float heatPermCoef = 1.0;
4600 EntityAI ent = this;
4601 while (ent)
4602 {
4603 heatPermCoef *= ent.GetHeatPermeabilityCoef();
4604 ent = ent.GetHierarchyParent();
4605 }
4606
4607 SetTemperatureEx(new TemperatureDataInterpolated(target,ETemperatureAccessTypes.ACCESS_WORLD,delta,GameConstants.TEMP_COEF_WORLD,heatPermCoef));
4608 }
4609 }
4610 }
4611
4612 void HierarchyCheck(out bool hasParent, out bool hasRootAsPlayer, out ItemBase refParentIB)
4613 {
4614 // hierarchy check for an item to decide whether it has some parent and it is in some player inventory
4615 EntityAI parent = GetHierarchyParent();
4616 if (!parent)
4617 {
4618 hasParent = false;
4619 hasRootAsPlayer = false;
4620 }
4621 else
4622 {
4623 hasParent = true;
4624 hasRootAsPlayer = (GetHierarchyRootPlayer() != null);
4625 refParentIB = ItemBase.Cast(parent);
4626 }
4627 }
4628
4629 protected void ProcessDecay(float delta, bool hasRootAsPlayer)
4630 {
4631 // this is stub, implemented on Edible_Base
4632 }
4633
4635 {
4636 // return true used on selected food clases so they can decay
4637 return false;
4638 }
4639
4640 protected bool CanProcessDecay()
4641 {
4642 // this is stub, implemented on Edible_Base class
4643 // used to determine whether it is still necessary for the food to decay
4644 return false;
4645 }
4646
4647 protected bool CanHaveWetness()
4648 {
4649 // return true used on selected items that have a wetness effect
4650 return false;
4651 }
4652
4655 {
4656 return !GetIsFrozen() && IsOpen();
4657 }
4658
4659 override void ProcessVariables(float elapsedTime)
4660 {
4661 bool hasParent = false, hasRootAsPlayer = false;
4662 ItemBase refParentIB;
4663
4664 bool wwtu = g_Game.IsWorldWetTempUpdateEnabled();
4665 bool foodDecay = g_Game.IsFoodDecayEnabled();
4666
4667 if (wwtu || foodDecay)
4668 {
4669 bool processWetness = wwtu && CanHaveWetness();
4670 bool processTemperature = wwtu && CanHaveTemperature();
4671 bool processDecay = foodDecay && CanDecay() && CanProcessDecay();
4672
4673 if (processWetness || processTemperature || processDecay)
4674 {
4675 HierarchyCheck(hasParent, hasRootAsPlayer, refParentIB);
4676
4677 if (processWetness)
4678 ProcessItemWetness(elapsedTime, hasParent, hasRootAsPlayer, refParentIB);
4679
4680 if (processTemperature)
4681 ProcessItemTemperature(elapsedTime, hasParent, hasRootAsPlayer, refParentIB);
4682
4683 if (processDecay)
4684 ProcessDecay(elapsedTime, hasRootAsPlayer);
4685 }
4686 }
4687 }
4688
4694
4696 {
4698 return Liquid.GetFreezeThreshold(GetLiquidType());
4699
4700 return super.GetTemperatureFreezeThreshold();
4701 }
4702
4704 {
4706 return Liquid.GetThawThreshold(GetLiquidType());
4707
4708 return super.GetTemperatureThawThreshold();
4709 }
4710
4712 {
4714 return Liquid.GetBoilThreshold(GetLiquidType());
4715
4716 return super.GetItemOverheatThreshold();
4717 }
4718
4720 {
4721 if (HasQuantity())
4723
4724 return super.GetTemperatureFreezeTime();
4725 }
4726
4727 override float GetTemperatureThawTime()
4728 {
4729 if (HasQuantity())
4731
4732 return super.GetTemperatureThawTime();
4733 }
4734
4736 void AffectLiquidContainerOnFill(int liquid_type, float amount);
4738 void AffectLiquidContainerOnTransfer(int liquidType, float amount, float sourceLiquidTemperature);
4739
4741 {
4742 return (item.IsKindOf("Cauldron") || item.IsKindOf("Pot") || item.IsKindOf("FryingPan") || item.IsKindOf("SmallProtectorCase") || (item.IsKindOf("PortableGasStove") && item.FindAttachmentBySlotName("CookingEquipment")));
4743 }
4744
4746 {
4747 MiscGameplayFunctions.TransferItemProperties(oldItem, this);
4748 }
4749
4752 {
4753 m_LightSourceItem = lightsource;
4754 }
4755
4757 {
4758 m_LightSourceItem = null;
4759 }
4760
4762 {
4763 return m_LightSourceItem;
4764 }
4765
4768 {
4769 return null;
4770 }
4771
4774 {
4775 return false;
4776 }
4777
4778 bool PairWithDevice(notnull ItemBase otherDevice)
4779 {
4780 if (g_Game.IsServer())
4781 {
4782 ItemBase explosive = otherDevice;
4784 if (!trg)
4785 {
4786 trg = RemoteDetonatorTrigger.Cast(otherDevice);
4787 explosive = this;
4788 }
4789
4790 explosive.PairRemote(trg);
4791 trg.SetControlledDevice(explosive);
4792
4794 trg.SetPersistentPairID(persistentID);
4795 explosive.SetPersistentPairID(persistentID);
4796
4797 return true;
4798 }
4799 return false;
4800 }
4801
4804 {
4805 float ret = 1.0;
4806 if (HasQuantity())
4807 ret *= GetQuantityNormalized();
4808 ret *= GetHealth01();
4809
4810 return ret;
4811 }
4812
4813 #ifdef DEVELOPER
4814 override void SetDebugItem()
4815 {
4816 super.SetDebugItem();
4817 _itemBase = this;
4818 }
4819
4820 override string GetDebugText()
4821 {
4822 string text = super.GetDebugText();
4823
4824 text += string.Format("Heat isolation(raw): %1\n", GetHeatIsolation());
4825 text += string.Format("Heat isolation(modified): %1\n", MiscGameplayFunctions.GetCurrentItemHeatIsolation(this));
4826
4827 return text;
4828 }
4829 #endif
4830
4832 {
4833 return true;
4834 }
4835
4837 {
4838 if (!owner)
4839 return;
4840
4841 PlayerBase playerBase = PlayerBase.Cast(owner);
4842 if (playerBase)
4843 {
4844 playerBase.NotifyPlayerLoadChanged();
4845 }
4846 }
4847
4849 {
4850 return false;
4851 }
4852
4854 {
4855 return true;
4856 }
4857
4859 {
4860 return true;
4861 }
4862
4864 //DEPRECATED BELOW
4866 // Backwards compatibility
4867 void ProcessItemWetnessAndTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
4868 {
4869 ProcessItemWetness(delta, hasParent, hasRootAsPlayer, refParentIB);
4870 ProcessItemTemperature(delta, hasParent, hasRootAsPlayer, refParentIB);
4871 }
4872
4873 // replaced by ItemSoundHandler
4881
4890 bool UsesGlobalDeploy(){return false;}
4891 bool CanPlayDeployLoopSound(){return false;}
4895 void SetIsPlaceSound(bool is_place_sound);
4896 void SetIsDeploySound(bool is_deploy_sound);
4897
4898 [Obsolete("Use ItemSoundHandler instead")]
4900 void PlayAttachSound(string slot_type)
4901 {
4902 if (!g_Game.IsHeadlessOrDedicatedServer())
4903 {
4904 if (ConfigIsExisting("attachSoundSet"))
4905 {
4906 string cfg_path = "";
4907 string soundset = "";
4908 string type_name = GetType();
4909
4910 TStringArray cfg_soundset_array = new TStringArray;
4911 TStringArray cfg_slot_array = new TStringArray;
4912 ConfigGetTextArray("attachSoundSet",cfg_soundset_array);
4913 ConfigGetTextArray("attachSoundSlot",cfg_slot_array);
4914
4915 if (cfg_soundset_array.Count() > 0 && cfg_soundset_array.Count() == cfg_slot_array.Count())
4916 {
4917 for (int i = 0; i < cfg_soundset_array.Count(); i++)
4918 {
4919 if (cfg_slot_array[i] == slot_type)
4920 {
4921 soundset = cfg_soundset_array[i];
4922 break;
4923 }
4924 }
4925 }
4926
4927 if (soundset != "")
4928 {
4929 EffectSound sound = SEffectManager.PlaySound(soundset, GetPosition());
4930 sound.SetAutodestroy(true);
4931 }
4932 }
4933 }
4934 }
4935
4936 void PlayDetachSound(string slot_type) {}
4937
4938 [Obsolete("1.30: No replacement")]
4940 {
4941 return ItemBaseType.Cast(GetEntityType()).m_HeatIsolation;
4942 }
4943
4944 [Obsolete("1.30: No replacement")]
4950}
4951
4952EntityAI SpawnItemOnLocation(string object_name, notnull InventoryLocation loc, bool full_quantity)
4953{
4954 EntityAI entity = SpawnEntity(object_name, loc, ECE_IN_INVENTORY, RF_DEFAULT);
4955 if (entity)
4956 {
4957 bool is_item = entity.IsInherited(ItemBase);
4958 if (is_item && full_quantity)
4959 {
4960 ItemBase item = ItemBase.Cast(entity);
4961 item.SetQuantity(item.GetQuantityInit());
4962 }
4963 }
4964 else
4965 {
4966 ErrorEx("Cannot spawn entity: " + object_name,ErrorExSeverity.INFO);
4967 return NULL;
4968 }
4969 return entity;
4970}
4971
4972void SetupSpawnedItem(ItemBase item, float health, float quantity)
4973{
4974 if (item)
4975 {
4976 if (health > 0)
4977 item.SetHealth("", "", health);
4978
4979 if (item.CanHaveTemperature())
4980 {
4981 item.SetTemperatureDirect(GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_MIDDLE);
4982 if (item.CanFreeze())
4983 item.SetFrozen(false);
4984 }
4985
4986 if (item.HasEnergyManager())
4987 {
4988 if (quantity >= 0)
4989 {
4990 item.GetCompEM().SetEnergy0To1(quantity);
4991 }
4992 else
4993 {
4994 item.GetCompEM().SetEnergy(Math.AbsFloat(quantity));
4995 }
4996 }
4997 else if (item.IsMagazine())
4998 {
4999 Magazine mag = Magazine.Cast(item);
5000 if (quantity >= 0)
5001 {
5002 mag.ServerSetAmmoCount(mag.GetAmmoMax() * quantity);
5003 }
5004 else
5005 {
5006 mag.ServerSetAmmoCount(Math.AbsFloat(quantity));
5007 }
5008
5009 }
5010 else
5011 {
5012 if (quantity >= 0)
5013 {
5014 item.SetQuantityNormalized(quantity, false);
5015 }
5016 else
5017 {
5018 item.SetQuantity(Math.AbsFloat(quantity));
5019 }
5020
5021 }
5022 }
5023}
5024
5025#ifdef DEVELOPER
5026ItemBase _itemBase;//watched item goes here(LCTRL+RMB->Watch)
5027#endif
ActionOverrideData TSelectableActionInfo
Param4< int, int, string, int > TSelectableActionInfoWithColor
EWetnessLevel
Определения 3_Game/DayZ/Entities/EntityAI.c:2
bool SetAttachSoundEvent()
bool SetDetachSoundEvent()
InventoryMode
NOTE: PREDICTIVE is not to be used at all in multiplayer.
const int INPUT_UDT_ITEM_MANIPULATION
eBleedingSourceType GetType()
override bool CanReleaseAttachment(EntityAI attachment)
bool IsDamageDestroyed(ActionTarget target)
Определения ActionBase.c:1275
void ActionBase()
Определения ActionBase.c:82
void ActionDropItem()
Определения ActionDropItem.c:34
void ActionManagerBase(PlayerBase player)
Определения ActionManagerBase.c:63
map< typename, ref array< ActionBase_Basic > > TInputActionMap
Определения ActionManagerClient.c:1
void AddAction(typename actionName)
Определения AdvancedCommunication.c:220
void RemoveAction(typename actionName)
Определения AdvancedCommunication.c:252
TInputActionMap m_InputActionMap
Определения AdvancedCommunication.c:137
bool m_ActionsInitialize
Определения AdvancedCommunication.c:138
override void GetActions(typename action_input_type, out array< ActionBase_Basic > actions)
Определения AdvancedCommunication.c:202
void InitializeActions()
Определения AdvancedCommunication.c:190
const int ECE_PLACE_ON_SURFACE
Определения CentralEconomy.c:38
proto native void SpawnEntity(string sClassName, vector vPos, float fRange, int iCount)
Spawn an entity through CE.
const int ECE_IN_INVENTORY
Определения CentralEconomy.c:37
const int RF_DEFAULT
Определения CentralEconomy.c:66
float quantityMax
Определения CfgPlayerSpawnDataJson.c:209
PlayerSpawnPresetDiscreteItemSetSlotData name
one set for cargo
PlayerSpawnPreset slotName
Open
Implementations only.
override void SetQuantity()
Определения ConstructionInfoIcons.c:298
override void EEOnCECreate()
Определения ContaminatedArea_Dynamic.c:42
CookingMethodType
Определения Cooking.c:2
DamageType
exposed from C++ (do not change)
Определения DamageSystem.c:11
DayZGame g_Game
Определения DayZGame.c:4074
DayZGame GetDayZGame()
Определения DayZGame.c:4076
string ammoType
Определения DustKickupEffects.c:24
vector position
Определения DustKickupEffects.c:20
vector orientation
Определения DustKickupEffects.c:21
EActions
Определения EActions.c:2
ERPCs
Определения ERPCs.c:2
PluginAdminLog m_AdminLog
Определения EmoteManager.c:152
const int MIN
Определения EnConvert.c:28
const int MAX
Определения EnConvert.c:27
override bool IsExplosive()
Определения ExplosivesBase.c:61
override bool IsPrepareToDelete()
Определения FireplaceBase.c:657
override bool CanHaveTemperature()
Определения FireplaceBase.c:575
class GP5GasMask extends MaskBase ItemBase
proto GizmoApi GetGizmoApi()
Empty
Определения Hand_States.c:14
FindInventoryLocationType
flags for searching locations in inventory
Определения InventoryLocation.c:18
InventoryLocationType
types of Inventory Location
Определения InventoryLocation.c:4
class BoxCollidingParams component
ComponentInfo for BoxCollidingResult.
override void SetQuantityNormalized(float value, bool destroy_config=true, bool destroy_forced=false)
Sets quantity in normalized 0..1 form between the item's Min a Max values as defined by item's config...
Определения ItemBase.c:3407
bool HasMuzzle()
Returns true if this item has a muzzle (weapons, suppressors)
Определения ItemBase.c:619
override bool IsSplitable()
Определения ItemBase.c:1528
override bool IsHologram()
Определения ItemBase.c:920
void ClearStopItemSoundServer()
Определения ItemBase.c:4505
bool IsOpen()
Определения ItemBase.c:4122
void SetResultOfSplit(bool value)
Определения ItemBase.c:2209
override float GetSingleInventoryItemWeightEx()
Определения ItemBase.c:3497
override float GetItemOverheatThreshold()
Определения ItemBase.c:4711
bool DamageItemInCargo(float damage)
Определения ItemBase.c:1491
void AffectLiquidContainerOnFill(int liquid_type, float amount)
from enviro source
void ProcessDecay(float delta, bool hasRootAsPlayer)
Определения ItemBase.c:4629
void OnAttachmentQuantityChanged(ItemBase item)
Called on server side when some attachment's quantity is changed. Call super.OnAttachmentQuantityChan...
Определения ItemBase.c:2010
float m_VarWet
Определения ItemBase.c:42
void PlayDeploySound()
static ref map< int, ref array< ref WeaponParticlesOnBulletCasingEject > > m_OnBulletCasingEjectEffect
Определения ItemBase.c:92
ref TIntArray m_SingleUseActions
Определения ItemBase.c:78
void LegacyStopItemSoundServer(int id)
Определения ItemBase.c:4483
void UpdateOverheating(ItemBase weapon=null, string ammoType="", ItemBase muzzle_owner=null, ItemBase suppressor=null, string config_to_search="")
Определения ItemBase.c:511
override void SetStoreLoadedQuantity(float value)
Определения ItemBase.c:3769
ScriptedLightBase GetLight()
ref array< ref OverheatingParticle > m_OverheatingParticles
Определения ItemBase.c:104
float GetDryingIncrement(EEnvironmentDryingCategories pCategory)
Определения ItemBase.c:3658
float GetHeatIsolationInit()
Определения ItemBase.c:4939
void SplitIntoStackMaxToInventoryLocation(notnull InventoryLocation dst)
Определения ItemBase.c:1796
bool IsNVG()
Определения ItemBase.c:841
bool m_IsSoundSynchRemote
Определения ItemBase.c:4880
float m_OverheatingShots
Определения ItemBase.c:99
bool IsFullQuantity()
Определения ItemBase.c:3491
bool CanExplodeInFire()
Определения ItemBase.c:2570
void LoadParticleConfigOnOverheating(int id)
Определения ItemBase.c:382
void StopItemDynamicPhysics()
Определения ItemBase.c:4530
override void NotifyPlayerLoadChanged(EntityAI owner)
Определения ItemBase.c:4836
bool m_RecipesInitialized
Определения ItemBase.c:31
bool IsActionTargetVisible()
Определения ItemBase.c:4374
float GetDeployTime()
how long it takes to deploy this item in seconds
Определения ItemBase.c:4354
override void RemoveAllAgentsExcept(int agent_to_keep)
Определения ItemBase.c:3979
void StartItemSoundClient(int id, int slotId=InventorySlots.INVALID)
Определения ItemBase.c:4456
override void CheckForRoofLimited(float timeTresholdMS=3000)
Roof check for entity, limited by time (anti-spam solution)
Определения ItemBase.c:4060
override void OnWetLevelChanged(EWetnessLevel newLevel, EWetnessLevel oldLevel)
Определения ItemBase.c:3747
override float GetTemperatureFreezeThreshold()
Определения ItemBase.c:4695
void AffectLiquidContainerOnTransfer(int liquidType, float amount, float sourceLiquidTemperature)
from other liquid container source
bool IsCargoException4x3(EntityAI item)
Определения ItemBase.c:4740
ref TIntArray m_InteractActions
Определения ItemBase.c:80
override void InsertAgent(int agent, float count=1)
Определения ItemBase.c:3984
override void CombineItemsEx(EntityAI entity2, bool use_stack_max=true)
Определения ItemBase.c:2238
float m_VarQuantity
Определения ItemBase.c:37
override float GetTemperatureFreezeTime()
Определения ItemBase.c:4719
void OnLiquidTypeChanged(int oldType, int newType)
Определения ItemBase.c:3888
string GetLockSoundSet()
Определения ItemBase.c:3823
bool CanDecay()
Определения ItemBase.c:4634
override void EOnContact(IEntity other, Contact extra)
Определения ItemBase.c:1119
void OnSyncVariables(ParamsReadContext ctx)
DEPRECATED (most likely)
Определения ItemBase.c:2853
override void SetCleanness(int value, bool allow_client=false)
Определения ItemBase.c:3791
void OnItemInHandsPlayerSwimStart(PlayerBase player)
override float GetWetMax()
Определения ItemBase.c:3722
void LockToParent()
Locks this item in it's current attachment slot of its parent. This makes the "locked" icon visible i...
Определения ItemBase.c:761
static ref map< int, ref array< ref WeaponParticlesOnFire > > m_OnFireEffect
Определения ItemBase.c:91
bool m_CanBeMovedOverride
Определения ItemBase.c:60
float GetEnergy()
Определения ItemBase.c:3613
override bool IsDetectableByVicinityCone()
Определения ItemBase.c:846
float GetDisinfectQuantity(int system=0, Param param1=null)
Определения ItemBase.c:608
void ProcessItemWetness(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
Определения ItemBase.c:4566
array< string > GetHeadHidingSelection()
Определения ItemBase.c:4518
void SoundSynchRemote()
bool CanBeCooked()
Определения ItemBase.c:2601
override void SplitIntoStackMaxEx(EntityAI destination_entity, int slot_id)
Определения ItemBase.c:1671
bool IsLiquidContainer()
Определения ItemBase.c:825
int m_ColorComponentR
Определения ItemBase.c:69
int m_ShotsToStartOverheating
Определения ItemBase.c:101
bool IsExternalLockType()
Определения ItemBase.c:4848
static void StopOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:4303
static void PlayBulletCasingEjectParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:4243
bool IsLiquidPresent()
Определения ItemBase.c:820
int m_Cleanness
Определения ItemBase.c:46
override bool IsPlayerInsideEx(DayZPlayer player, string selection)
useful for construction and inventory related systems
Определения ItemBase.c:883
bool CanHaveWetness()
Определения ItemBase.c:4647
void RefreshAudioVisualsOnClient(CookingMethodType cooking_method, bool is_done, bool is_empty, bool is_burned)
cooking-related effect methods
Определения Bottle_Base.c:158
override string ChangeIntoOnAttach(string slot)
Определения ItemBase.c:1350
void SplitItemToInventoryLocation(notnull InventoryLocation dst)
Определения ItemBase.c:1917
void SoundSynchRemoteReset()
ItemSoundHandler GetItemSoundHandler()
Определения ItemBase.c:4407
override void CombineItemsClient(EntityAI entity2, bool use_stack_max=true)
Определения ItemBase.c:786
bool Repair(PlayerBase player, ItemBase item_repair_kit, float specialty_weight)
Определения ItemBase.c:2623
override bool IsStoreLoad()
Определения ItemBase.c:3764
void ConvertEnergyToQuantity()
Определения ItemBase.c:3639
int GetLiquidContainerMask()
Определения ItemBase.c:830
bool IsCombineAll(ItemBase other_item, bool use_stack_max=false)
Определения ItemBase.c:2199
float m_HeatIsolation
Определения ItemBase.c:53
static void PlayOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:4263
override void RemoveAgent(int agent_id)
Определения ItemBase.c:3965
bool CanPlayDetachSound()
Определения ItemBase.c:4858
void SplitIntoStackMaxToInventoryLocationClient(notnull InventoryLocation dst)
Определения ItemBase.c:1749
bool m_CanPlayImpactSound
Определения ItemBase.c:49
static void ToggleDebugActionsMask(int mask)
Определения ItemBase.c:719
void OnActivatedByTripWire()
override float GetQuantityNormalized()
Gets quantity in normalized 0..1 form between the item's Min a Max values as defined by item's config...
Определения ItemBase.c:3416
override int GetQuantityMin()
Определения ItemBase.c:3470
ref array< ref ItemSoundEvent > m_SoundEventQueue
Определения ItemBase.c:121
bool GetActionWidgetOverride(out typename name)
If we need a different (handheld)item action widget displayed, the logic goes in here.
Определения ItemBase.c:4773
override void RemoveAllAgents()
Определения ItemBase.c:3974
void LegacyItemSoundSync()
Определения ItemBase.c:3293
override float GetQuantity()
Определения ItemBase.c:3486
const int ITEM_SOUNDS_MAX
Определения ItemBase.c:116
void SetQuantityMax()
Определения ItemBase.c:3394
override bool HasQuantity()
Определения ItemBase.c:3481
override void OnWetChanged(float newVal, float oldVal)
Определения ItemBase.c:3737
int GetItemSize()
Определения ItemBase.c:2630
override string GetAttachmentSoundType()
Определения ItemBase.c:4392
bool m_ThrowItemOnDrop
Определения ItemBase.c:58
override void SetStoreLoad(bool value)
Определения ItemBase.c:3759
override string ChangeIntoOnDetach()
Определения ItemBase.c:1374
void ClearStartItemSoundServer()
Определения ItemBase.c:4945
string GetLoopDeploySoundset()
Определения LargeTent.c:151
override void OnEnergyAdded()
Определения ItemBase.c:3631
override float GetWetInit()
Определения ItemBase.c:3732
float GetBaitEffectivity()
generic effectivity as a bait for animal catching
Определения ItemBase.c:4803
int NameToID(string name)
Определения ItemBase.c:2840
override bool IsBeingPlaced()
Определения ItemBase.c:904
void StopOverheating(ItemBase weapon=null, string ammoType="", ItemBase muzzle_owner=null, ItemBase suppressor=null, string config_to_search="")
Определения ItemBase.c:518
string GetColorString()
Returns item's PROCEDURAL color as formated string, i.e. "#(argb,8,8,3)color(0.15,...
Определения ItemBase.c:3854
int GetLiquidTypeInit()
Определения ItemBase.c:3878
override void SetWetMax()
Определения ItemBase.c:3712
override void SetTakeable(bool pState)
Определения ItemBase.c:4362
bool CanBeDigged()
Определения ItemBase.c:925
void SetIsHologram(bool is_hologram)
Определения ItemBase.c:940
bool IsResultOfSplit()
Определения ItemBase.c:2204
float m_VarWetPrev
Определения ItemBase.c:43
override void OnRightClick()
Определения ItemBase.c:2059
void StartOverheating(ItemBase weapon=null, string ammoType="", ItemBase muzzle_owner=null, ItemBase suppressor=null, string config_to_search="")
Определения ItemBase.c:505
int m_SoundSyncStop
Определения ItemBase.c:118
ref TIntArray m_ContinuousActions
Определения ItemBase.c:79
void UpdateAllOverheatingParticles()
Определения ItemBase.c:546
bool AllowFoodConsumption()
Определения ItemBase.c:3810
int m_VarLiquidType
Определения ItemBase.c:54
void SaveAgents(ParamsWriteContext ctx)
Определения ItemBase.c:4052
float GetOverheatingCoef()
Определения ItemBase.c:538
int m_ImpactSoundSurfaceHash
Определения ItemBase.c:51
int m_SoundSyncPlay
Определения ItemBase.c:117
override void SetWet(float value, bool allow_client=false)
Определения ItemBase.c:3688
int m_MaxOverheatingValue
Определения ItemBase.c:102
void SetupSpawnedItem(ItemBase item, float health, float quantity)
Определения ItemBase.c:4972
bool m_IsTakeable
Определения ItemBase.c:57
static ref map< string, int > m_WeaponTypeToID
Определения ItemBase.c:94
void KillAllOverheatingParticles()
Определения ItemBase.c:574
string GetPlaceSoundset()
override void ProcessVariables(float elapsedTime)
Определения ItemBase.c:4659
float GetUnitWeight(bool include_wetness=true)
Obsolete, use GetWeightEx instead.
Определения ItemBase.c:3573
float GetProtectionLevel(int type, bool consider_filter=false, int system=0)
Определения ItemBase.c:4073
override bool IsOneHandedBehaviour()
Определения ItemBase.c:4332
bool IsCoverFaceForShave(string slot_name)
DEPRECATED in use, but returns correct values nontheless. Check performed elsewhere.
Определения ItemBase.c:4561
ItemBase GetLightSourceItem()
Определения ItemBase.c:4761
void SetInventoryLocationToVicinityOrCurrent(EntityAI root, inout InventoryLocation dst)
Определения ItemBase.c:2123
void Close()
float m_OverheatingDecayInterval
Определения ItemBase.c:103
void SplitIntoStackMaxCargoClient(EntityAI destination_entity, int idx, int row, int col)
Определения ItemBase.c:1771
bool IsLightSource()
Определения ItemBase.c:865
bool LoadAgents(ParamsReadContext ctx, int version)
Определения ItemBase.c:4045
bool CanProcessDecay()
Определения ItemBase.c:4640
void SplitIntoStackMaxCargo(EntityAI destination_entity, int idx, int row, int col)
Определения ItemBase.c:1838
void PlayDetachSound(string slot_type)
Определения ItemBase.c:4936
void IncreaseOverheating(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:443
override float GetTemperatureThawTime()
Определения ItemBase.c:4727
bool can_this_be_combined
Определения ItemBase.c:62
array< int > GetValidFinishers()
returns an array of possible finishers
Определения ItemBase.c:4767
override int GetLiquidType()
Определения ItemBase.c:3883
int GetLockType()
Определения ItemBase.c:3818
override void SetQuantityToMinimum()
Определения ItemBase.c:3400
EffectSound m_SoundDeploy
Определения ItemBase.c:4877
int m_SoundSyncSlotID
Определения ItemBase.c:119
void SetIsPlaceSound(bool is_place_sound)
void RegisterOverheatingParticle(Particle p, float min_heat_coef, float max_heat_coef, int particle_id, Object parent, vector local_pos, vector local_ori)
Определения ItemBase.c:524
int GetQuantityInit()
Определения ItemBase.c:3475
void CombineItems(ItemBase other_item, bool use_stack_max=true)
Определения ItemBase.c:2243
override float GetTemperatureThawThreshold()
Определения ItemBase.c:4703
override bool ReadVarsFromCTX(ParamsReadContext ctx, int version=-1)
Определения ItemBase.c:2998
bool m_WantPlayImpactSound
Определения ItemBase.c:48
ref map< int, ref array< ref WeaponParticlesOnOverheating > > m_OnOverheatingEffect
Определения ItemBase.c:93
int m_ColorComponentG
Определения ItemBase.c:70
EntityAI SpawnItemOnLocation(string object_name, notnull InventoryLocation loc, bool full_quantity)
Определения ItemBase.c:4952
bool CanBeConsumed(ConsumeConditionData data=null)
Items cannot be consumed if frozen by default. Override for exceptions.
Определения ItemBase.c:4654
float m_StoreLoadedQuantity
Определения ItemBase.c:40
override float GetWetMin()
Определения ItemBase.c:3727
override int GetQuickBarBonus()
Определения ItemBase.c:218
int m_ColorComponentA
Определения ItemBase.c:72
void CheckOverheating(ItemBase weapon=null, string ammoType="", ItemBase muzzle_owner=null, ItemBase suppressor=null, string config_to_search="")
Определения ItemBase.c:459
void SplitIntoStackMaxHands(PlayerBase player)
Определения ItemBase.c:1889
void SetIsDeploySound(bool is_deploy_sound)
string IDToName(int id)
Определения ItemBase.c:2846
bool CanBeMovedOverride()
Определения ItemBase.c:2645
float ComputeQuantityUsedEx(ItemBase other_item, bool use_stack_max=true)
Определения ItemBase.c:2219
float GetItemAttachOffset()
Определения ItemBase.c:3786
float GetFilterDamageRatio()
Определения ItemBase.c:613
bool HasFoodStage()
Определения ItemBase.c:2589
static bool HasDebugActionsMask(int mask)
Определения ItemBase.c:699
void DoAmmoExplosion()
Определения ItemBase.c:1426
void RemoveAudioVisualsOnClient()
Определения Bottle_Base.c:151
void RemoveLightSourceItem()
Определения ItemBase.c:4756
int GetMuzzleID()
Returns global muzzle ID. If not found, then it gets automatically registered.
Определения ItemBase.c:628
ref Timer m_CheckOverheating
Определения ItemBase.c:100
void SetZoneDamageCEInit()
Sets zone damages to match randomized global health set by CE (CE spawn only)
Определения ItemBase.c:4548
string GetDeploySoundset()
Определения LargeTent.c:146
void OnApply(PlayerBase player)
static int GetDebugActionsMask()
Определения ItemBase.c:694
override void EEHitBy(TotalDamageResult damageResult, int damageType, EntityAI source, int component, string dmgZone, string ammo, vector modelPos, float speedCoef)
Определения ItemBase.c:1450
int GetNumberOfItems()
Returns the number of items in cargo, otherwise returns 0(non-cargo objects). Recursive.
Определения ItemBase.c:3550
void OnOverheatingDecay()
Определения ItemBase.c:481
bool ShouldSplitQuantity(float quantity)
Определения ItemBase.c:1541
bool UsesGlobalDeploy()
Определения ItemBase.c:4890
bool m_IsDeploySound
Определения ItemBase.c:4879
void StopItemSoundServer(int id)
Определения ItemBase.c:4495
void PerformDamageSystemReinit()
Определения ItemBase.c:4536
float GetTemperaturePerQuantityWeight()
Used in heat comfort calculations only!
Определения ItemBase.c:4690
bool CanBeUsedForSuicide()
Определения ItemBase.c:4831
static void SetDebugActionsMask(int mask)
Определения ItemBase.c:704
override void ClearInventory()
Определения ItemBase.c:3592
static void UpdateOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:4283
void SetCEBasedQuantity()
Определения ItemBase.c:732
bool ContainsAgent(int agent_id)
Определения ItemBase.c:3952
void SetIsBeingPlaced(bool is_being_placed)
Определения ItemBase.c:909
override void AddWet(float value)
Определения ItemBase.c:3707
override void OnMovedInsideCargo(EntityAI container)
Определения ItemBase.c:980
bool HidesSelectionBySlot()
Определения ItemBase.c:4523
FoodStage GetFoodStage()
overridden on Edible_Base; so we don't have to parse configs all the time
Определения ItemBase.c:2596
void PlayAttachSound(string slot_type)
Plays sound on item attach. Be advised, the config structure may slightly change in 1....
Определения ItemBase.c:4900
void SplitIntoStackMax(EntityAI destination_entity, int slot_id, PlayerBase player)
Определения ItemBase.c:1584
float GetWeightSpecialized(bool forceRecalc=false)
Определения ItemBase.c:3511
void UnlockFromParent()
Unlocks this item from its attachment slot of its parent.
Определения ItemBase.c:774
EffectSound m_DeployLoopSoundEx
Определения ItemBase.c:4876
void StopDeployLoopSoundEx()
override bool IsHeavyBehaviour()
Определения ItemBase.c:4324
void ProcessItemWetnessAndTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
Определения ItemBase.c:4867
string GetExplosiveTriggerSlotName()
Определения ItemBase.c:858
void SplitIntoStackMaxHandsClient(PlayerBase player)
Определения ItemBase.c:1865
ref Timer m_PhysDropTimer
Определения ItemBase.c:110
void OnQuantityChanged(float delta)
Called on server side when this item's quantity is changed. Call super.OnQuantityChanged(); first whe...
Определения ItemBase.c:1987
void HierarchyCheck(out bool hasParent, out bool hasRootAsPlayer, out ItemBase refParentIB)
Определения ItemBase.c:4612
float GetItemModelLength()
Определения ItemBase.c:3781
bool m_IsResultOfSplit string m_SoundAttType
distinguish if item has been created as new or it came from splitting (server only flag)
Определения ItemBase.c:67
void ~ItemBase()
Определения ItemBase.c:659
void PlayPlaceSound()
override int GetTargetQuantityMax(int attSlotID=-1)
Определения ItemBase.c:3449
override bool KindOf(string tag)
Определения ItemBase.c:2735
void PlayDeployFinishSound()
bool IsDeploySound()
Определения ItemBase.c:4894
void FlushItemSoundQueue()
Определения ItemBase.c:4464
class ItemSoundEvent m_ItemTypeActionsMap
bool m_IsOverheatingEffectActive
Определения ItemBase.c:98
bool DamageItemAttachments(float damage)
Определения ItemBase.c:1511
override void DeSerializeNumericalVars(array< float > floats)
Определения ItemBase.c:2903
bool IsPlaceSound()
Определения ItemBase.c:4893
bool CanBeCookedOnStick()
Определения ItemBase.c:2606
void StartItemSoundServer(int id, int slotId)
Определения ItemBase.c:4436
bool CanPlayDeployLoopSound()
Определения ItemBase.c:4891
override void OnItemAttachmentSlotChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
Определения ItemBase.c:1157
bool CanPlayAttachSound()
Определения ItemBase.c:4853
static void AddDebugActionsMask(int mask)
Определения ItemBase.c:709
override void SplitIntoStackMaxClient(EntityAI destination_entity, int slot_id)
Определения ItemBase.c:1561
override float GetWet()
Определения ItemBase.c:3717
bool AddQuantity(float value, bool destroy_config=true, bool destroy_forced=false)
add item quantity[related to varQuantity... config entry], destroy_config = true > if the quantity re...
Определения ItemBase.c:3389
static int m_LastRegisteredWeaponID
Определения ItemBase.c:95
void SetCanBeMovedOverride(bool setting)
Определения ItemBase.c:2652
override void WriteVarsToCTX(ParamsWriteContext ctx)
Определения ItemBase.c:2962
static void RemoveDebugActionsMask(int mask)
Определения ItemBase.c:714
bool m_CanThisBeSplit
Определения ItemBase.c:63
override int GetAgents()
Определения ItemBase.c:3999
float GetOverheatingValue()
Определения ItemBase.c:438
void TransferAgents(int agents)
transfer agents from another item
Определения ItemBase.c:3993
bool CanEat()
Определения ItemBase.c:2576
int ComputeQuantityUsed(ItemBase other_item, bool use_stack_max=true)
Определения ItemBase.c:2214
void PlayDeployLoopSoundEx()
ItemBase SplitIntoStackMaxToInventoryLocationEx(notnull InventoryLocation dst)
Определения ItemBase.c:1801
bool CanRepair(ItemBase item_repair_kit)
Определения ItemBase.c:2616
void MessageToOwnerStatus(string text)
Send message to owner player in grey color.
Определения ItemBase.c:2665
bool IsColorSet()
Определения ItemBase.c:3848
bool m_IsHologram
Определения ItemBase.c:56
static int m_DebugActionsMask
Определения ItemBase.c:30
void PreLoadSoundAttachmentType()
Attachment Sound Type getting from config file.
Определения ItemBase.c:4380
bool m_ItemBeingDroppedPhys
Определения ItemBase.c:59
override int GetCleanness()
Определения ItemBase.c:3805
void TransferModifiers(PlayerBase reciever)
appears to be deprecated, legacy code
bool m_FixDamageSystemInit
Определения ItemBase.c:61
float m_ImpactSpeed
Определения ItemBase.c:50
bool m_IsStoreLoad
Определения ItemBase.c:64
float GetSoakingIncrement(EEnvironmentSoakingCategories pCategory)
Определения ItemBase.c:3663
bool IsSoundSynchRemote()
Определения ItemBase.c:4892
void LoadParticleConfigOnFire(int id)
Определения ItemBase.c:313
void MessageToOwnerImportant(string text)
Send message to owner player in red color.
Определения ItemBase.c:2719
ItemBase m_LightSourceItem
Определения ItemBase.c:76
int m_AttachedAgents
Определения ItemBase.c:84
override bool IsFacingPlayerEx(DayZPlayer player, string selection)
Определения ItemBase.c:877
void SplitItem(PlayerBase player)
Определения ItemBase.c:1953
float m_VarQuantityPrev
Определения ItemBase.c:38
override void SetLiquidType(int value, bool allow_client=false)
Определения ItemBase.c:3867
float GetSingleInventoryItemWeight()
Определения ItemBase.c:3506
void MessageToOwnerAction(string text)
Send message to owner player in yellow color.
Определения ItemBase.c:2683
override EWetnessLevel GetWetLevel()
Определения ItemBase.c:3752
override void SerializeNumericalVars(array< float > floats_out)
Определения ItemBase.c:2867
int m_ColorComponentB
Определения ItemBase.c:71
override float GetStoreLoadedQuantity()
Определения ItemBase.c:3774
void ProcessItemTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
Определения ItemBase.c:4592
bool m_IsBeingPlaced
Определения ItemBase.c:55
void UpdateQuickbarShortcutVisibility(PlayerBase player)
To be called on moving item within character's inventory; 'player' should never be null.
Определения ItemBase.c:3895
string GetDeployFinishSoundset()
void OnAttachmentQuantityChangedEx(ItemBase item, float delta)
Called on server side when some attachment's quantity is changed. Call super.OnAttachmentQuantityChan...
Определения ItemBase.c:2016
float GetHeatIsolation()
Определения ItemBase.c:3653
void ExplodeAmmo()
Определения ItemBase.c:1413
static void PlayFireParticles(ItemBase weapon, int muzzle_index, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:4223
void AddLightSourceItem(ItemBase lightsource)
Adds a light source child.
Определения ItemBase.c:4751
EffectSound m_SoundDeployFinish
Определения ItemBase.c:4874
EffectSound m_SoundPlace
Определения ItemBase.c:4875
float GetQuantityNormalizedScripted()
Определения ItemBase.c:3421
bool IsOverheatingEffectActive()
Определения ItemBase.c:476
void MessageToOwnerFriendly(string text)
Send message to owner player in green color.
Определения ItemBase.c:2701
override bool IsItemBase()
Определения ItemBase.c:2729
bool m_IsPlaceSound
Определения ItemBase.c:4878
ref ItemSoundHandler m_ItemSoundHandler
Определения ItemBase.c:122
void CopyScriptPropertiesFrom(EntityAI oldItem)
Определения ItemBase.c:4745
void GetRecipesActions(Man player, out TSelectableActionInfoArray outputList)
Определения ItemBase.c:2277
override bool IsTwoHandedBehaviour()
Определения ItemBase.c:4340
bool PairWithDevice(notnull ItemBase otherDevice)
Определения ItemBase.c:4778
override int GetQuantityMax()
Определения ItemBase.c:3435
override void OnEnergyConsumed()
Определения ItemBase.c:3624
void ItemSoundHandler(ItemBase parent)
Определения ItemSoundHandler.c:31
string Type
Определения JsonDataContaminatedArea.c:11
EffectSound m_LockingSound
Определения Land_Underground_Entrance.c:344
string GetDebugText()
Определения ModifierBase.c:71
@ LOWEST
Определения PPEConstants.c:54
void PluginItemDiagnostic()
Определения PluginItemDiagnostic.c:74
PluginBase GetPlugin(typename plugin_type)
Определения PluginManager.c:326
override RemotelyActivatedItemBehaviour GetRemotelyActivatedItemBehaviour()
Определения RemoteDetonator.c:272
override void OnActivatedByItem(notnull ItemBase item)
Called when this item is activated by other.
Определения RemoteDetonator.c:305
int particle_id
Определения SmokeSimulation.c:28
ETemperatureAccessTypes
Определения TemperatureAccessConstants.c:2
override void Explode(int damageType, string ammoType="")
Определения Trap_LandMine.c:220
bool m_Initialized
Определения UiHintPanel.c:317
Определения ActionTakeItem.c:7
Определения AmmunitionPiles.c:84
proto native int GetItemCount()
proto native EntityAI GetItem(int index)
represents base for cargo storage for entities
Определения Cargo.c:7
Super root of all classes in Enforce script.
Определения EnScript.c:11
float GetEnergyAtSpawn()
Определения ComponentEnergyManager.c:1312
void SetEnergy0To1(float energy01)
Energy manager: Sets stored energy for this device between 0 and MAX based on relative input value be...
Определения ComponentEnergyManager.c:537
bool HasConversionOfEnergyToQuantity()
Energy manager: Returns true if this item automatically converts its energy to quantity.
Определения ComponentEnergyManager.c:1042
float GetEnergy0To1()
Energy manager: Returns % of stored energy this device has as float (from 0.0 to 1....
Определения ComponentEnergyManager.c:1211
float GetEnergyMaxPristine()
Energy manager: Returns the maximum amount of energy this device can store. It's damage is NOT taken ...
Определения ComponentEnergyManager.c:1307
Определения Contact.c:10
Определения ZombieBase.c:2
Определения DayZPlayerImplement.c:87
static void LogError(string message=LOG_DEFAULT, string plugin=LOG_DEFAULT, string author=LOG_DEFAULT, string label=LOG_DEFAULT, string entity=LOG_DEFAULT)
Prints debug message as error message.
Определения 3_Game/DayZ/tools/Debug.c:318
static void Log(string message=LOG_DEFAULT, string plugin=LOG_DEFAULT, string author=LOG_DEFAULT, string label=LOG_DEFAULT, string entity=LOG_DEFAULT)
Prints debug message with normal prio.
Определения 3_Game/DayZ/tools/Debug.c:183
static void ActionLog(string message=LOG_DEFAULT, string plugin=LOG_DEFAULT, string author=LOG_DEFAULT, string label=LOG_DEFAULT, string entity=LOG_DEFAULT)
Определения 3_Game/DayZ/tools/Debug.c:188
Определения 3_Game/DayZ/tools/Debug.c:2
Определения SCARH.c:98
override void SetAutodestroy(bool auto_destroy)
Sets whether Effect automatically cleans up when it stops.
Определения EffectSound.c:607
Wrapper class for managing sound through SEffectManager.
Определения EffectSound.c:5
override bool IsMan()
Определения 3_Game/DayZ/Entities/Man.c:48
proto native EntityAI GetAttachmentFromIndex(int index)
proto native bool GetCurrentInventoryLocation(out notnull InventoryLocation loc)
returns information about current item location
proto native bool EnumerateInventory(InventoryTraversalType tt, out array< EntityAI > items)
enumerate inventory using traversal type and filling items array
proto native CargoBase GetCargo()
cargo
const int c_InventoryReservationTimeoutShortMS
static proto native EntityAI LocationCreateEntity(notnull InventoryLocation inv_loc, string type, int iSetupFlags, int iRotation)
creates new item directly at location
proto native int AttachmentCount()
Returns count of attachments attached to this item.
proto native bool FindFreeLocationFor(notnull EntityAI item, FindInventoryLocationType flags, out notnull InventoryLocation loc)
FindFreeLocationFor.
script counterpart to engine's class Inventory
proto void SelectObject(Object object)
proto void SelectPhysics(Physics physics)
Определения EnEntity.c:165
Определения Feet.c:1
proto native bool IsValid()
verify current set inventory location
proto native EntityAI GetParent()
returns parent of current inventory location
proto native int GetSlot()
returns slot id if current type is Attachment
proto native int GetCol()
returns column of cargo if current type is Cargo / ProxyCargo
proto native int GetRow()
returns row of cargo if current type is Cargo / ProxyCargo
bool WriteToContext(ParamsWriteContext ctx)
Определения InventoryLocation.c:507
proto native int GetType()
returns type of InventoryLocation
proto native int GetIdx()
returns index of cargo if current type is Cargo / ProxyCargo
proto native void SetCargo(notnull EntityAI parent, EntityAI e, int idx, int row, int col, bool flip)
sets current inventory location type to Cargo with coordinates (idx, row, col)
proto native bool GetFlip()
returns flip status of cargo
proto native EntityAI GetItem()
returns item of current inventory location
InventoryLocation.
Определения InventoryLocation.c:30
const int INVALID
Invalid slot (-1)
Определения InventorySlots.c:17
static proto native bool IsSlotIdValid(int slotId)
verifies existence of the slot id
static proto native int GetStackMaxForSlotId(int slot_Id)
provides access to slot configuration
Определения InventorySlots.c:6
override bool CanDisplayCargo()
Определения TentBase.c:93
override void OnInventoryEnter(Man player)
Определения BarbedWire.c:203
override string GetFoldSoundset()
Определения BaseBuildingBase.c:97
override bool CanPutAsAttachment(EntityAI parent)
Определения ItemBase.c:3
override bool CanReceiveItemIntoCargo(EntityAI item)
Определения TentBase.c:936
override bool OnStoreLoad(ParamsReadContext ctx, int version)
Определения GardenBase.c:199
override void OnWasDetached(EntityAI parent, int slot_id)
override void EEOnAfterLoad()
Определения GardenBase.c:242
override void EEDelete(EntityAI parent)
Определения BaseBuildingBase.c:409
override bool CanBeRepairedByCrafting()
Определения TentBase.c:88
override void OnPlacementStarted(Man player)
Определения BatteryCharger.c:382
override void OnItemLocationChanged(EntityAI old_owner, EntityAI new_owner)
Определения BarbedWire.c:357
override bool IsElectricAppliance()
Определения BatteryCharger.c:48
override bool IsItemTent()
Определения TentBase.c:83
override string GetLoopFoldSoundset()
Определения BaseBuildingBase.c:102
override bool CanMakeGardenplot()
Определения FieldShovel.c:3
override void GetDebugActions(out TSelectableActionInfoArrayEx outputList)
Определения PowerGenerator.c:392
override void EEItemLocationChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
Определения HandcuffsLocked.c:12
override WrittenNoteData GetWrittenNoteData()
Определения Paper.c:30
override int GetDamageSystemVersionChange()
Определения BaseBuildingBase.c:1133
override bool SetQuantity(float value, bool destroy_config=true, bool destroy_forced=false, bool allow_client=false, bool clamp_to_stack_max=true)
Определения PileOfBricks.c:64
override void InitItemVariables()
Определения Matchbox.c:3
override void OnCreatePhysics()
Определения BaseBuildingBase.c:489
override string GetDeploySoundset()
Определения BarbedWire.c:392
override float GetBandagingEffectivity()
Определения BandageDressing.c:49
override bool OnAction(int action_id, Man player, ParamsReadContext ctx)
Определения PowerGenerator.c:404
override void EEHealthLevelChanged(int oldLevel, int newLevel, string zone)
Определения BaseBuildingBase.c:497
override void OnStoreSave(ParamsWriteContext ctx)
Определения GardenBase.c:266
override void AfterStoreLoad()
Определения BarbedWire.c:155
override int GetOnDigWormsAmount()
Определения FieldShovel.c:27
override bool IsSelfAdjustingTemperature()
Определения PortableGasStove.c:291
override bool IsPlayerInside(PlayerBase player, string selection)
Определения BaseBuildingBase.c:938
override void OnVariablesSynchronized()
Определения GardenBase.c:97
override void RefreshPhysics()
Определения BatteryCharger.c:365
override bool CanObstruct()
Определения BaseBuildingBase.c:73
override void OnWasAttached(EntityAI parent, int slot_id)
override bool CanReceiveAttachment(EntityAI attachment, int slotId)
Определения BatteryCharger.c:244
override bool CanPutInCargo(EntityAI parent)
Определения GardenBase.c:331
override string GetLoopDeploySoundset()
Определения BarbedWire.c:397
override void OnPlacementComplete(Man player, vector position="0 0 0", vector orientation="0 0 0")
Определения BarbedWire.c:372
override void OnInventoryExit(Man player)
Определения BatteryCharger.c:347
override bool IsTakeable()
Определения BaseBuildingBase.c:909
override bool IsIgnoredByConstruction()
Определения BaseBuildingBase.c:1065
override void InitItemSounds()
Определения BaseBuildingBase.c:83
override void EEKilled(Object killer)
Определения HandcuffsLocked.c:70
override void OnCombine(ItemBase other_item)
Определения BandageDressing.c:71
override bool CanExplodeInFire()
Определения LargeGasCannister.c:3
override bool IsFacingPlayer(PlayerBase player, string selection)
Определения BaseBuildingBase.c:933
override bool CanBeCombined(EntityAI other_item, bool reservation_check=true, bool stack_max_limit=false)
Определения Rag.c:61
override bool IsBloodContainer()
Определения BloodContainerBase.c:10
override bool CanBeSplit()
Определения Rag.c:34
override bool IsDeployable()
Определения BaseBuildingBase.c:354
override void OnRPC(PlayerIdentity sender, int rpc_type, ParamsReadContext ctx)
Определения ToolBase.c:24
override bool CanBeDisinfected()
Определения BandageDressing.c:54
override float GetInfectionChance(int system=0, Param param=null)
Определения BandageDressing.c:59
override void OnEndPlacement()
Определения KitBase.c:65
int m_LiquidContainerMask
Определения ItemBaseType.c:23
ref TStringArray m_HeadHidingSelections
Определения ItemBaseType.c:53
int m_VarQuantityMax
Определения ItemBaseType.c:16
float m_HeatIsolation
Определения ItemBaseType.c:42
bool m_CanBeSplit
Определения ItemBaseType.c:10
int m_CleannessInit
Cleanness config.
Определения ItemBaseType.c:19
int m_VarQuantityMin
Определения ItemBaseType.c:15
int m_LockType
Attachment locking.
Определения ItemBaseType.c:30
float m_VarWetInit
Wetness config.
Определения ItemBaseType.c:38
int m_QuickBarBonus
Определения ItemBaseType.c:27
float m_VarStackMax
Определения ItemBaseType.c:35
float m_VarWetMax
Определения ItemBaseType.c:40
int m_CleannessMax
Определения ItemBaseType.c:21
string m_LockSoundSet
Определения ItemBaseType.c:49
ref TIntFloatMap m_DryingIncrements
Определения ItemBaseType.c:52
bool m_HideSelectionsBySlot
Определения ItemBaseType.c:9
float m_VarWetMin
Определения ItemBaseType.c:39
int m_VarQuantityInit
Определения ItemBaseType.c:14
float m_TemperaturePerQuantityWeight
Определения ItemBaseType.c:47
int m_VarLiquidTypeInit
Определения ItemBaseType.c:25
bool m_CanBeDigged
Определения ItemBaseType.c:8
float m_ItemModelLength float m_ItemAttachOffset
Определения ItemBaseType.c:45
int m_CleannessMin
Определения ItemBaseType.c:20
ref TIntFloatMap m_SoakingIncrements
Определения ItemBaseType.c:51
Определения ItemBaseType.c:5
int m_SlotId
Определения ItemBase.c:12
int m_SoundId
Определения ItemBase.c:11
void ItemSoundEvent(int soundId, int slotId)
Определения ItemBase.c:14
Определения ItemBase.c:10
static const int FLOAT
Определения UtilityClasses.c:4
static bool IsActionLogEnable()
Определения 3_Game/DayZ/tools/Debug.c:749
Определения EnMath.c:7
Определения ObjectTyped.c:2
float GetOverheatingLimitMax()
Определения WeaponParticles.c:417
void SetOverheatingLimitMax(float max)
Определения WeaponParticles.c:407
void SetParticleParams(int particle_id, Object parent, vector local_pos, vector local_ori)
Определения WeaponParticles.c:422
float GetOverheatingLimitMin()
Определения WeaponParticles.c:412
Particle GetParticle()
Определения WeaponParticles.c:397
void SetOverheatingLimitMin(float min)
Определения WeaponParticles.c:402
void RegisterParticle(Particle p)
Определения WeaponParticles.c:392
Определения PPEConstants.c:68
Base Param Class with no parameters. Used as general purpose parameter overloaded with Param1 to Para...
Определения param.c:12
void Stop()
Legacy function for backwards compatibility with 1.14 and below.
Определения Particle.c:266
Legacy way of using particles in the game.
Определения Particle.c:7
Определения PlayerBaseClient.c:2
The class that will be instanced (moddable)
Определения gameplay.c:389
void SetControlledDevice(EntityAI pDevice)
Определения RemoteDetonator.c:140
bool OnStoreLoad(ParamsReadContext ctx, int version)
void OnStoreSave(ParamsWriteContext ctx)
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.
Определения EffectManager.c:178
static void DestroyEffect(Effect effect)
Unregisters, stops and frees the Effect.
Определения EffectManager.c:280
Manager class for managing Effect (EffectParticle, EffectSound)
Определения EffectManager.c:6
proto native void Send()
proto static native bool CanStoreInputUserData()
Returns true when the channel is free, AND the InputBuffer is NOT full (same as '!...
Определения gameplay.c:121
proto native void Send(Object target, int rpc_type, bool guaranteed, PlayerIdentity recipient=NULL)
Initiate remote procedure call. When called on client, RPC is evaluated on server; When called on ser...
Определения gameplay.c:105
proto bool Write(void value_out)
proto bool Read(void value_in)
bool m_Loop
Определения ItemSoundHandler.c:5
Определения DayZPlayerImplement.c:39
proto native float GetDamage(string zoneName, string healthType)
Определения DamageSystem.c:2
const float DEFAULT_DEPLOY
Определения ActionConstants.c:38
Определения ActionConstants.c:28
override void Refresh()
Определения ChatInputMenu.c:70
Определения DayZGame.c:64
script counterpart to engine's class Weapon
void SetCalcDetails(string details)
Определения 3_Game/DayZ/tools/Debug.c:934
void OnRPC(PlayerIdentity sender, int rpc_type, ParamsReadContext ctx)
Определения WrittenNoteData.c:13
Определения WrittenNoteData.c:2
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
Определения Transport.c:70
static proto native float Distance(vector v1, vector v2)
Returns the distance between tips of two 3D vectors.
Определения EnConvert.c:119
Serializer ParamsReadContext
Определения gameplay.c:15
InventoryTraversalType
tree traversal type, for more see http://en.wikipedia.org/wiki/Tree_traversal
Определения gameplay.c:6
Serializer ParamsWriteContext
Определения gameplay.c:16
DayZGame GetGame()
Определения gameplay.c:636
const int DEF_DUST_PARTICLE_BREATH
Определения 3_Game/DayZ/constants.c:549
const int DEF_BIOLOGICAL
Определения 3_Game/DayZ/constants.c:547
const int DEF_CHEMICAL
Определения 3_Game/DayZ/constants.c:548
const int DEF_DUST_PARTICLE_EYES
Определения 3_Game/DayZ/constants.c:550
const int COMP_TYPE_ENERGY_MANAGER
Определения Component.c:9
ErrorExSeverity
Определения EnDebug.c:62
void Error(string err)
Messagebox with error message.
Определения EnDebug.c:90
enum ShapeType ErrorEx
proto native void SetColor(int color)
const float WETNESS_RATE_WETTING_INSIDE
Определения 3_Game/DayZ/constants.c:972
const float ITEM_TEMPERATURE_TO_EXPLODE_MIN
misc
Определения 3_Game/DayZ/constants.c:1075
const float WETNESS_RATE_WETTING_LIQUID
Определения 3_Game/DayZ/constants.c:973
static proto bool CastTo(out Class to, Class from)
Try to safely down-cast base class to child class.
array< int > TIntArray
Определения EnScript.c:733
class array< Class T > TStringArray
void Obsolete(string msg="")
Определения EnScript.c:371
EntityEvent
Entity events for event-mask, or throwing event from code.
Определения EnEntity.c:45
const float TEMP_COEF_WORLD
Определения 3_Game/DayZ/constants.c:1003
static const float TEMPERATURE_TIME_THAW_MIN
Определения 3_Game/DayZ/constants.c:994
static const float TEMPERATURE_TIME_FREEZE_MIN
Определения 3_Game/DayZ/constants.c:993
static const float ITEM_TEMPERATURE_NEUTRAL_ZONE_MIDDLE
Определения 3_Game/DayZ/constants.c:856
const float ITEM_TEMPERATURE_QUANTITY_WEIGHT_MULTIPLIER
Определения 3_Game/DayZ/constants.c:854
const int STATE_RUINED
Определения 3_Game/DayZ/constants.c:909
const int VARIABLE_LIQUIDTYPE
Определения 3_Game/DayZ/constants.c:669
const int VARIABLE_CLEANNESS
Определения 3_Game/DayZ/constants.c:672
const int VARIABLE_COLOR
Определения 3_Game/DayZ/constants.c:671
const int VARIABLE_TEMPERATURE
Определения 3_Game/DayZ/constants.c:667
const int VARIABLE_QUANTITY
Определения 3_Game/DayZ/constants.c:665
const int VARIABLE_WET
Определения 3_Game/DayZ/constants.c:668
const float STATE_SOAKING_WET
Определения 3_Game/DayZ/constants.c:934
const int LIQUID_NONE
Определения 3_Game/DayZ/constants.c:566
static proto float Max(float x, float y)
Returns bigger of two given values.
static proto float Floor(float f)
Returns floor of value.
static proto float Lerp(float a, float b, float time)
Linearly interpolates between 'a' and 'b' given 'time'.
static float RandomFloatInclusive(float min, float max)
Returns a random float number between and min [inclusive] and max [inclusive].
Определения EnMath.c:106
static proto float Round(float f)
Returns mathematical round of value.
static proto float RandomFloat(float min, float max)
Returns a random float number between and min[inclusive] and max[exclusive].
static proto float Clamp(float value, float min, float max)
Clamps 'value' to 'min' if it is lower than 'min', or to 'max' if it is higher than 'max'.
static proto float InverseLerp(float a, float b, float value)
Calculates the linear value that produces the interpolant value within the range [a,...
static proto int RandomInt(int min, int max)
Returns a random int number between and min [inclusive] and max [exclusive].
static proto float AbsFloat(float f)
Returns absolute value.
const int MENU_INVENTORY
Определения 3_Game/DayZ/constants.c:186
proto native bool dBodyIsDynamic(notnull IEntity ent)
const int SAT_CRAFTING
Определения 3_Game/DayZ/constants.c:485
const int SAT_DEBUG_ACTION
Определения 3_Game/DayZ/constants.c:486
vector GetPosition()
Get the world position of the Effect.
Определения Effect.c:473
proto string Get(int index)
Gets n-th character from string.
static proto string Format(string fmt, 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)
Gets n-th character from string.
const int CALL_CATEGORY_GAMEPLAY
Определения 3_Game/DayZ/tools/tools.c:10
const int CALL_CATEGORY_SYSTEM
Определения 3_Game/DayZ/tools/tools.c:8
proto native int GetColor()