DayZ 1.28
DayZ Explorer by KGB
 
Загрузка...
Поиск...
Не найдено

◆ OnWasDetached()

override void SpawnItemOnLocation::OnWasDetached ( EntityAI parent,
int slot_id )
private

См. определение в файле ItemBase.c строка 6231

6235{
6236 override bool CanPutAsAttachment(EntityAI parent)
6237 {
6238 return true;
6239 }
6240};
6241
6242//const bool QUANTITY_DEBUG_REMOVE_ME = false;
6243
6244class ItemBase extends InventoryItem
6245{
6249
6251
6252 static int m_DebugActionsMask;
6254 // ============================================
6255 // Variable Manipulation System
6256 // ============================================
6257 // Quantity
6258
6259 float m_VarQuantity;
6260 float m_VarQuantityPrev;//for client to know quantity changed during synchronization
6262 int m_VarQuantityMin;
6263 int m_VarQuantityMax;
6264 int m_Count;
6265 float m_VarStackMax;
6266 float m_StoreLoadedQuantity = float.LOWEST;
6267 // Wet
6268 float m_VarWet;
6269 float m_VarWetPrev;//for client to know wetness changed during synchronization
6270 float m_VarWetInit;
6271 float m_VarWetMin;
6272 float m_VarWetMax;
6273 // Cleanness
6274 int m_Cleanness;
6275 int m_CleannessInit;
6276 int m_CleannessMin;
6277 int m_CleannessMax;
6278 // impact sounds
6280 bool m_CanPlayImpactSound = true;
6281 float m_ImpactSpeed;
6283 //
6284 float m_HeatIsolation;
6285 float m_ItemModelLength;
6286 float m_ItemAttachOffset; // Offset length for when the item is attached e.g. to weapon
6288 int m_VarLiquidType;
6289 int m_ItemBehaviour; // -1 = not specified; 0 = heavy item; 1= onehanded item; 2 = twohanded item
6290 int m_QuickBarBonus;
6291 bool m_IsBeingPlaced;
6292 bool m_IsHologram;
6293 bool m_IsTakeable;
6294 bool m_ThrowItemOnDrop;
6297 bool m_FixDamageSystemInit = false; //can be changed on storage version check
6298 bool can_this_be_combined; //Check if item can be combined
6299 bool m_CanThisBeSplit; //Check if item can be split
6300 bool m_IsStoreLoad = false;
6301 bool m_CanShowQuantity;
6302 bool m_HasQuantityBar;
6303 protected bool m_CanBeDigged;
6304 protected bool m_IsResultOfSplit
6305
6306 string m_SoundAttType;
6307 // items color variables
6312 //-------------------------------------------------------
6313
6314 // light source managing
6316
6320
6321 //==============================================
6322 // agent system
6323 private int m_AttachedAgents;
6324
6326 void TransferModifiers(PlayerBase reciever);
6327
6328
6329 // Weapons & suppressors particle effects
6334 static int m_LastRegisteredWeaponID = 0;
6335
6336 // Overheating effects
6338 float m_OverheatingShots;
6339 ref Timer m_CheckOverheating;
6340 int m_ShotsToStartOverheating = 0; // After these many shots, the overheating effect begins
6341 int m_MaxOverheatingValue = 0; // Limits the number of shots that will be tracked
6342 float m_OverheatingDecayInterval = 1; // Timer's interval for decrementing overheat effect's lifespan
6343 ref array <ref OverheatingParticle> m_OverheatingParticles;
6344
6346 protected bool m_HideSelectionsBySlot;
6347
6348 // Admin Log
6349 PluginAdminLog m_AdminLog;
6350
6351 // misc
6352 ref Timer m_PhysDropTimer;
6353
6354 // Attachment Locking variables
6355 ref array<int> m_CompatibleLocks;
6356 protected int m_LockType;
6357 protected ref EffectSound m_LockingSound;
6358 protected string m_LockSoundSet;
6359
6360 // ItemSoundHandler
6361 protected const int ITEM_SOUNDS_MAX = 63; // optimize network synch
6362 protected int m_SoundSyncPlay; // id for sound to play
6363 protected int m_SoundSyncStop; // id for sound to stop
6365
6366 //temperature
6367 private float m_TemperaturePerQuantityWeight;
6368
6369 // -------------------------------------------------------------------------
6370 void ItemBase()
6371 {
6372 SetEventMask(EntityEvent.INIT); // Enable EOnInit event
6376
6377 if (!GetGame().IsDedicatedServer())
6378 {
6379 if (HasMuzzle())
6380 {
6382
6384 {
6386 }
6387 }
6388
6390 m_ActionsInitialize = false;
6391 }
6392
6393 m_OldLocation = null;
6394
6395 if (GetGame().IsServer())
6396 {
6397 m_AdminLog = PluginAdminLog.Cast(GetPlugin(PluginAdminLog));
6398 }
6399
6400 if (ConfigIsExisting("headSelectionsToHide"))
6401 {
6403 ConfigGetTextArray("headSelectionsToHide",m_HeadHidingSelections);
6404 }
6405
6406 m_HideSelectionsBySlot = false;
6407 if (ConfigIsExisting("hideSelectionsByinventorySlot"))
6408 {
6409 m_HideSelectionsBySlot = ConfigGetBool("hideSelectionsByinventorySlot");
6410 }
6411
6412 m_QuickBarBonus = Math.Max(0, ConfigGetInt("quickBarBonus"));
6413
6414 m_IsResultOfSplit = false;
6415
6417 }
6418
6419 override void InitItemVariables()
6420 {
6421 super.InitItemVariables();
6422
6423 m_VarQuantityInit = ConfigGetInt("varQuantityInit");
6424 m_VarQuantity = m_VarQuantityInit;//should be by the CE, this is just a precaution
6425 m_VarQuantityMin = ConfigGetInt("varQuantityMin");
6426 m_VarQuantityMax = ConfigGetInt("varQuantityMax");
6427 m_VarStackMax = ConfigGetFloat("varStackMax");
6428 m_Count = ConfigGetInt("count");
6429
6430 m_CanShowQuantity = ConfigGetBool("quantityShow");
6431 m_HasQuantityBar = ConfigGetBool("quantityBar");
6432
6433 m_CleannessInit = ConfigGetInt("varCleannessInit");
6435 m_CleannessMin = ConfigGetInt("varCleannessMin");
6436 m_CleannessMax = ConfigGetInt("varCleannessMax");
6437
6438 m_WantPlayImpactSound = false;
6439 m_ImpactSpeed = 0.0;
6440
6441 m_VarWetInit = ConfigGetFloat("varWetInit");
6443 m_VarWetMin = ConfigGetFloat("varWetMin");
6444 m_VarWetMax = ConfigGetFloat("varWetMax");
6445
6446 m_LiquidContainerMask = ConfigGetInt("liquidContainerType");
6447 if (IsLiquidContainer() && GetQuantity() != 0)
6449 m_IsBeingPlaced = false;
6450 m_IsHologram = false;
6451 m_IsTakeable = true;
6452 m_CanBeMovedOverride = false;
6456 m_CanBeDigged = ConfigGetBool("canBeDigged");
6457
6458 m_CompatibleLocks = new array<int>();
6459 ConfigGetIntArray("compatibleLocks", m_CompatibleLocks);
6460 m_LockType = ConfigGetInt("lockType");
6461
6462 //Define if item can be split and set ability to be combined accordingly
6463 m_CanThisBeSplit = false;
6464 can_this_be_combined = false;
6465 if (ConfigIsExisting("canBeSplit"))
6466 {
6467 can_this_be_combined = ConfigGetBool("canBeSplit");
6469 }
6470
6471 m_ItemBehaviour = -1;
6472 if (ConfigIsExisting("itemBehaviour"))
6473 m_ItemBehaviour = ConfigGetInt("itemBehaviour");
6474
6475 //RegisterNetSyncVariableInt("m_VariablesMask");
6476 if (HasQuantity()) RegisterNetSyncVariableFloat("m_VarQuantity", GetQuantityMin(), m_VarQuantityMax);
6477 RegisterNetSyncVariableFloat("m_VarWet", GetWetMin(), GetWetMax(), 2);
6478 RegisterNetSyncVariableInt("m_VarLiquidType");
6479 RegisterNetSyncVariableInt("m_Cleanness",0,1);
6480
6481 RegisterNetSyncVariableBoolSignal("m_WantPlayImpactSound");
6482 RegisterNetSyncVariableFloat("m_ImpactSpeed");
6483 RegisterNetSyncVariableInt("m_ImpactSoundSurfaceHash");
6484
6485 RegisterNetSyncVariableInt("m_ColorComponentR", 0, 255);
6486 RegisterNetSyncVariableInt("m_ColorComponentG", 0, 255);
6487 RegisterNetSyncVariableInt("m_ColorComponentB", 0, 255);
6488 RegisterNetSyncVariableInt("m_ColorComponentA", 0, 255);
6489
6490 RegisterNetSyncVariableBool("m_IsBeingPlaced");
6491 RegisterNetSyncVariableBool("m_IsTakeable");
6492 RegisterNetSyncVariableBool("m_IsHologram");
6493
6494 InitItemSounds();
6496 {
6497 RegisterNetSyncVariableInt("m_SoundSyncPlay", 0, ITEM_SOUNDS_MAX);
6498 RegisterNetSyncVariableInt("m_SoundSyncStop", 0, ITEM_SOUNDS_MAX);
6499 }
6500
6501 m_LockSoundSet = ConfigGetString("lockSoundSet");
6502
6504 if (ConfigIsExisting("temperaturePerQuantityWeight"))
6505 m_TemperaturePerQuantityWeight = ConfigGetFloat("temperaturePerQuantityWeight");
6506
6507 }
6508
6509 override int GetQuickBarBonus()
6510 {
6511 return m_QuickBarBonus;
6512 }
6513
6514 void InitializeActions()
6515 {
6517 if (!m_InputActionMap)
6518 {
6520 m_InputActionMap = iam;
6521 SetActions();
6523 }
6524 }
6525
6526 override void GetActions(typename action_input_type, out array<ActionBase_Basic> actions)
6527 {
6529 {
6530 m_ActionsInitialize = true;
6532 }
6533
6534 actions = m_InputActionMap.Get(action_input_type);
6535 }
6536
6537 void SetActions()
6538 {
6539 AddAction(ActionTakeItem);
6540 AddAction(ActionTakeItemToHands);
6541 AddAction(ActionWorldCraft);
6543 AddAction(ActionAttachWithSwitch);
6544 }
6545
6546 void SetActionAnimOverrides(); // Override action animation for specific item
6547
6548 void AddAction(typename actionName)
6549 {
6550 ActionBase action = ActionManagerBase.GetAction(actionName);
6551
6552 if (!action)
6553 {
6554 Debug.LogError("Action " + actionName + " dosn't exist!");
6555 return;
6556 }
6557
6558 typename ai = action.GetInputType();
6559 if (!ai)
6560 {
6561 m_ActionsInitialize = false;
6562 return;
6563 }
6564
6565 array<ActionBase_Basic> action_array = m_InputActionMap.Get(ai);
6566 if (!action_array)
6567 {
6568 action_array = new array<ActionBase_Basic>;
6569 m_InputActionMap.Insert(ai, action_array);
6570 }
6571 if (LogManager.IsActionLogEnable())
6572 {
6573 Debug.ActionLog(action.ToString() + " -> " + ai, this.ToString() , "n/a", "Add action");
6574 }
6575
6576 if (action_array.Find(action) != -1)
6577 {
6578 Debug.Log("Action " + action.Type() + " already added to " + this + ", skipping!");
6579 }
6580 else
6581 {
6582 action_array.Insert(action);
6583 }
6584 }
6585
6586 void RemoveAction(typename actionName)
6587 {
6588 PlayerBase player = PlayerBase.Cast(GetGame().GetPlayer());
6589 ActionBase action = player.GetActionManager().GetAction(actionName);
6590 typename ai = action.GetInputType();
6591 array<ActionBase_Basic> action_array = m_InputActionMap.Get(ai);
6592
6593 if (action_array)
6594 {
6595 action_array.RemoveItem(action);
6596 }
6597 }
6598
6599 // Allows override of default action command per item, defined in the SetActionAnimOverrides() of the item's class
6600 // Set -1 for params which should stay in default state
6601 void OverrideActionAnimation(typename action, int commandUID, int stanceMask = -1, int commandUIDProne = -1)
6602 {
6603 ActionOverrideData overrideData = new ActionOverrideData();
6604 overrideData.m_CommandUID = commandUID;
6605 overrideData.m_CommandUIDProne = commandUIDProne;
6606 overrideData.m_StanceMask = stanceMask;
6607
6608 TActionAnimOverrideMap actionMap = m_ItemActionOverrides.Get(action);
6609 if (!actionMap) // create new map of action > overidables map
6610 {
6611 actionMap = new TActionAnimOverrideMap();
6612 m_ItemActionOverrides.Insert(action, actionMap);
6613 }
6614
6615 actionMap.Insert(this.Type(), overrideData); // insert item -> overrides
6616
6617 }
6618
6619 void OnItemInHandsPlayerSwimStart(PlayerBase player);
6620
6621 ScriptedLightBase GetLight();
6622
6623 // Loads muzzle flash particle configuration from config and saves it to a map for faster access
6624 void LoadParticleConfigOnFire(int id)
6625 {
6626 if (!m_OnFireEffect)
6628
6631
6632 string config_to_search = "CfgVehicles";
6633 string muzzle_owner_config;
6634
6635 if (!m_OnFireEffect.Contains(id))
6636 {
6637 if (IsInherited(Weapon))
6638 config_to_search = "CfgWeapons";
6639
6640 muzzle_owner_config = config_to_search + " " + GetType() + " ";
6641
6642 string config_OnFire_class = muzzle_owner_config + "Particles " + "OnFire ";
6643
6644 int config_OnFire_subclass_count = GetGame().ConfigGetChildrenCount(config_OnFire_class);
6645
6646 if (config_OnFire_subclass_count > 0)
6647 {
6648 array<ref WeaponParticlesOnFire> WPOF_array = new array<ref WeaponParticlesOnFire>;
6649
6650 for (int i = 0; i < config_OnFire_subclass_count; i++)
6651 {
6652 string particle_class = "";
6653 GetGame().ConfigGetChildName(config_OnFire_class, i, particle_class);
6654 string config_OnFire_entry = config_OnFire_class + particle_class;
6655 WeaponParticlesOnFire WPOF = new WeaponParticlesOnFire(this, config_OnFire_entry);
6656 WPOF_array.Insert(WPOF);
6657 }
6658
6659
6660 m_OnFireEffect.Insert(id, WPOF_array);
6661 }
6662 }
6663
6664 if (!m_OnBulletCasingEjectEffect.Contains(id))
6665 {
6666 config_to_search = "CfgWeapons"; // Bullet Eject efect is supported on weapons only.
6667 muzzle_owner_config = config_to_search + " " + GetType() + " ";
6668
6669 string config_OnBulletCasingEject_class = muzzle_owner_config + "Particles " + "OnBulletCasingEject ";
6670
6671 int config_OnBulletCasingEject_count = GetGame().ConfigGetChildrenCount(config_OnBulletCasingEject_class);
6672
6673 if (config_OnBulletCasingEject_count > 0 && IsInherited(Weapon))
6674 {
6675 array<ref WeaponParticlesOnBulletCasingEject> WPOBE_array = new array<ref WeaponParticlesOnBulletCasingEject>;
6676
6677 for (i = 0; i < config_OnBulletCasingEject_count; i++)
6678 {
6679 string particle_class2 = "";
6680 GetGame().ConfigGetChildName(config_OnBulletCasingEject_class, i, particle_class2);
6681 string config_OnBulletCasingEject_entry = config_OnBulletCasingEject_class + particle_class2;
6682 WeaponParticlesOnBulletCasingEject WPOBE = new WeaponParticlesOnBulletCasingEject(this, config_OnBulletCasingEject_entry);
6683 WPOBE_array.Insert(WPOBE);
6684 }
6685
6686
6687 m_OnBulletCasingEjectEffect.Insert(id, WPOBE_array);
6688 }
6689 }
6690 }
6691
6692 // Loads muzzle flash particle configuration from config and saves it to a map for faster access
6694 {
6697
6698 if (!m_OnOverheatingEffect.Contains(id))
6699 {
6700 string config_to_search = "CfgVehicles";
6701
6702 if (IsInherited(Weapon))
6703 config_to_search = "CfgWeapons";
6704
6705 string muzzle_owner_config = config_to_search + " " + GetType() + " ";
6706 string config_OnOverheating_class = muzzle_owner_config + "Particles " + "OnOverheating ";
6707
6708 if (GetGame().ConfigIsExisting(config_OnOverheating_class))
6709 {
6710
6711 m_ShotsToStartOverheating = GetGame().ConfigGetFloat(config_OnOverheating_class + "shotsToStartOverheating");
6712
6714 {
6715 m_ShotsToStartOverheating = -1; // This prevents futher readings from config for future creations of this item
6716 string error = "Error reading config " + GetType() + ">Particles>OnOverheating - Parameter shotsToStartOverheating is configured wrong or is missing! Its value must be 1 or higher!";
6717 Error(error);
6718 return;
6719 }
6720
6721 m_OverheatingDecayInterval = GetGame().ConfigGetFloat(config_OnOverheating_class + "overheatingDecayInterval");
6722 m_MaxOverheatingValue = GetGame().ConfigGetFloat(config_OnOverheating_class + "maxOverheatingValue");
6723
6724
6725
6726 int config_OnOverheating_subclass_count = GetGame().ConfigGetChildrenCount(config_OnOverheating_class);
6727 array<ref WeaponParticlesOnOverheating> WPOOH_array = new array<ref WeaponParticlesOnOverheating>;
6728
6729 for (int i = 0; i < config_OnOverheating_subclass_count; i++)
6730 {
6731 string particle_class = "";
6732 GetGame().ConfigGetChildName(config_OnOverheating_class, i, particle_class);
6733 string config_OnOverheating_entry = config_OnOverheating_class + particle_class;
6734 int entry_type = GetGame().ConfigGetType(config_OnOverheating_entry);
6735
6736 if (entry_type == CT_CLASS)
6737 {
6738 WeaponParticlesOnOverheating WPOF = new WeaponParticlesOnOverheating(this, config_OnOverheating_entry);
6739 WPOOH_array.Insert(WPOF);
6740 }
6741 }
6742
6743
6744 m_OnOverheatingEffect.Insert(id, WPOOH_array);
6745 }
6746 }
6747 }
6748
6749 float GetOverheatingValue()
6750 {
6751 return m_OverheatingShots;
6752 }
6753
6754 void IncreaseOverheating(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
6755 {
6756 if (m_MaxOverheatingValue > 0)
6757 {
6759
6760 if (!m_CheckOverheating)
6762
6764 m_CheckOverheating.Run(m_OverheatingDecayInterval, this, "OnOverheatingDecay");
6765
6766 CheckOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
6767 }
6768 }
6769
6770 void CheckOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
6771 {
6773 UpdateOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
6774
6776 StartOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
6777
6779 StopOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
6780
6782 {
6784 }
6785 }
6786
6788 {
6790 }
6791
6792 void OnOverheatingDecay()
6793 {
6794 if (m_MaxOverheatingValue > 0)
6795 m_OverheatingShots -= 1 + m_OverheatingShots / m_MaxOverheatingValue; // The hotter a barrel is, the faster it needs to cool down.
6796 else
6798
6799 if (m_OverheatingShots <= 0)
6800 {
6803 }
6804 else
6805 {
6806 if (!m_CheckOverheating)
6808
6810 m_CheckOverheating.Run(m_OverheatingDecayInterval, this, "OnOverheatingDecay");
6811 }
6812
6813 CheckOverheating(this, "", this);
6814 }
6815
6816 void StartOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
6817 {
6819 ItemBase.PlayOverheatingParticles(this, ammoType, this, suppressor, "CfgWeapons");
6820 }
6821
6822 void UpdateOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
6823 {
6825 ItemBase.UpdateOverheatingParticles(this, ammoType, this, suppressor, "CfgWeapons");
6827 }
6828
6829 void StopOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
6830 {
6832 ItemBase.StopOverheatingParticles(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
6833 }
6834
6835 void RegisterOverheatingParticle(Particle p, float min_heat_coef, float max_heat_coef, int particle_id, Object parent, vector local_pos, vector local_ori)
6836 {
6838 m_OverheatingParticles = new array<ref OverheatingParticle>;
6839
6840 OverheatingParticle OP = new OverheatingParticle();
6841 OP.RegisterParticle(p);
6842 OP.SetOverheatingLimitMin(min_heat_coef);
6843 OP.SetOverheatingLimitMax(max_heat_coef);
6844 OP.SetParticleParams(particle_id, parent, local_pos, local_ori);
6845
6846 m_OverheatingParticles.Insert(OP);
6847 }
6848
6849 float GetOverheatingCoef()
6850 {
6851 if (m_MaxOverheatingValue > 0)
6853
6854 return -1;
6855 }
6856
6858 {
6860 {
6861 float overheat_coef = GetOverheatingCoef();
6862 int count = m_OverheatingParticles.Count();
6863
6864 for (int i = count; i > 0; --i)
6865 {
6866 int id = i - 1;
6867 OverheatingParticle OP = m_OverheatingParticles.Get(id);
6868 Particle p = OP.GetParticle();
6869
6870 float overheat_min = OP.GetOverheatingLimitMin();
6871 float overheat_max = OP.GetOverheatingLimitMax();
6872
6873 if (overheat_coef < overheat_min && overheat_coef >= overheat_max)
6874 {
6875 if (p)
6876 {
6877 p.Stop();
6878 OP.RegisterParticle(null);
6879 }
6880 }
6881 }
6882 }
6883 }
6884
6886 {
6888 {
6889 for (int i = m_OverheatingParticles.Count(); i > 0; i--)
6890 {
6891 int id = i - 1;
6892 OverheatingParticle OP = m_OverheatingParticles.Get(id);
6893
6894 if (OP)
6895 {
6896 Particle p = OP.GetParticle();
6897
6898 if (p)
6899 {
6900 p.Stop();
6901 }
6902
6903 delete OP;
6904 }
6905 }
6906
6907 m_OverheatingParticles.Clear();
6909 }
6910 }
6911
6913 float GetInfectionChance(int system = 0, Param param = null)
6914 {
6915 return 0.0;
6916 }
6917
6918
6919 float GetDisinfectQuantity(int system = 0, Param param1 = null)
6920 {
6921 return 250;//default value
6922 }
6923
6924 float GetFilterDamageRatio()
6925 {
6926 return 0;
6927 }
6928
6930 bool HasMuzzle()
6931 {
6932 if (IsInherited(Weapon) || IsInherited(SuppressorBase))
6933 return true;
6934
6935 return false;
6936 }
6937
6939 int GetMuzzleID()
6940 {
6941 if (!m_WeaponTypeToID)
6943
6944 if (m_WeaponTypeToID.Contains(GetType()))
6945 {
6946 return m_WeaponTypeToID.Get(GetType());
6947 }
6948 else
6949 {
6950 // Register new weapon ID
6952 }
6953
6955 }
6956
6963 {
6964 return -1;
6965 }
6966
6967
6968
6969 // -------------------------------------------------------------------------
6970 void ~ItemBase()
6971 {
6972 if (GetGame() && GetGame().GetPlayer() && (!GetGame().IsDedicatedServer()))
6973 {
6974 PlayerBase player = PlayerBase.Cast(GetGame().GetPlayer());
6975 int r_index = player.GetHumanInventory().FindUserReservedLocationIndex(this);
6976
6977 if (r_index >= 0)
6978 {
6979 InventoryLocation r_il = new InventoryLocation;
6980 player.GetHumanInventory().GetUserReservedLocation(r_index,r_il);
6981
6982 player.GetHumanInventory().ClearUserReservedLocationAtIndex(r_index);
6983 int r_type = r_il.GetType();
6984 if (r_type == InventoryLocationType.CARGO || r_type == InventoryLocationType.PROXYCARGO)
6985 {
6986 r_il.GetParent().GetOnReleaseLock().Invoke(this);
6987 }
6988 else if (r_type == InventoryLocationType.ATTACHMENT)
6989 {
6990 r_il.GetParent().GetOnAttachmentReleaseLock().Invoke(this, r_il.GetSlot());
6991 }
6992
6993 }
6994
6995 player.GetHumanInventory().ClearUserReservedLocation(this);
6996 }
6997
6998 if (m_LockingSound)
6999 SEffectManager.DestroyEffect(m_LockingSound);
7000 }
7001
7002
7003
7004 // -------------------------------------------------------------------------
7005 static int GetDebugActionsMask()
7006 {
7007 return ItemBase.m_DebugActionsMask;
7008 }
7009
7010 static bool HasDebugActionsMask(int mask)
7011 {
7012 return ItemBase.m_DebugActionsMask & mask;
7013 }
7014
7015 static void SetDebugActionsMask(int mask)
7016 {
7017 ItemBase.m_DebugActionsMask = mask;
7018 }
7019
7020 static void AddDebugActionsMask(int mask)
7021 {
7022 ItemBase.m_DebugActionsMask |= mask;
7023 }
7024
7025 static void RemoveDebugActionsMask(int mask)
7026 {
7027 ItemBase.m_DebugActionsMask &= ~mask;
7028 }
7029
7030 static void ToggleDebugActionsMask(int mask)
7031 {
7032 if (HasDebugActionsMask(mask))
7033 {
7035 }
7036 else
7037 {
7038 AddDebugActionsMask(mask);
7039 }
7040 }
7041
7042 // -------------------------------------------------------------------------
7043 void SetCEBasedQuantity()
7044 {
7045 if (GetEconomyProfile())
7046 {
7047 float q_max = GetEconomyProfile().GetQuantityMax();
7048 if (q_max > 0)
7049 {
7050 float q_min = GetEconomyProfile().GetQuantityMin();
7051 float quantity_randomized = Math.RandomFloatInclusive(q_min, q_max);
7052
7053 if (HasComponent(COMP_TYPE_ENERGY_MANAGER))//more direct access for speed
7054 {
7055 ComponentEnergyManager comp = GetCompEM();
7056 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
7057 {
7058 comp.SetEnergy0To1(quantity_randomized);
7059 }
7060 }
7061 else if (HasQuantity())
7062 {
7063 SetQuantityNormalized(quantity_randomized, false);
7064 //PrintString("<==> Normalized quantity for item: "+ GetType()+", qmin:"+q_min.ToString()+"; qmax:"+q_max.ToString()+";quantity:" +quantity_randomized.ToString());
7065 }
7066
7067 }
7068 }
7069 }
7070
7072 void LockToParent()
7073 {
7074 EntityAI parent = GetHierarchyParent();
7075
7076 if (parent)
7077 {
7078 InventoryLocation inventory_location_to_lock = new InventoryLocation;
7079 GetInventory().GetCurrentInventoryLocation(inventory_location_to_lock);
7080 parent.GetInventory().SetSlotLock(inventory_location_to_lock.GetSlot(), true);
7081 }
7082 }
7083
7085 void UnlockFromParent()
7086 {
7087 EntityAI parent = GetHierarchyParent();
7088
7089 if (parent)
7090 {
7091 InventoryLocation inventory_location_to_unlock = new InventoryLocation;
7092 GetInventory().GetCurrentInventoryLocation(inventory_location_to_unlock);
7093 parent.GetInventory().SetSlotLock(inventory_location_to_unlock.GetSlot(), false);
7094 }
7095 }
7096
7097 override void CombineItemsClient(EntityAI entity2, bool use_stack_max = true)
7098 {
7099 /*
7100 ref Param1<EntityAI> item = new Param1<EntityAI>(entity2);
7101 RPCSingleParam(ERPCs.RPC_ITEM_COMBINE, item, GetGame().GetPlayer());
7102 */
7103 ItemBase item2 = ItemBase.Cast(entity2);
7104
7105 if (GetGame().IsClient())
7106 {
7107 if (ScriptInputUserData.CanStoreInputUserData())
7108 {
7109 ScriptInputUserData ctx = new ScriptInputUserData;
7111 ctx.Write(-1);
7112 ItemBase i1 = this; // @NOTE: workaround for correct serialization
7113 ctx.Write(i1);
7114 ctx.Write(item2);
7115 ctx.Write(use_stack_max);
7116 ctx.Write(-1);
7117 ctx.Send();
7118
7119 if (IsCombineAll(item2, use_stack_max))
7120 {
7121 GetGame().GetPlayer().GetInventory().AddInventoryReservationEx(item2,null,GameInventory.c_InventoryReservationTimeoutShortMS);
7122 }
7123 }
7124 }
7125 else if (!GetGame().IsMultiplayer())
7126 {
7127 CombineItems(item2, use_stack_max);
7128 }
7129 }
7130
7131 bool IsLiquidPresent()
7132 {
7133 return (GetLiquidType() != 0 && HasQuantity());
7134 }
7135
7136 bool IsLiquidContainer()
7137 {
7138 return m_LiquidContainerMask != 0;
7139 }
7140
7142 {
7143 return m_LiquidContainerMask;
7144 }
7145
7146 bool IsBloodContainer()
7147 {
7148 //m_LiquidContainerMask & GROUP_LIQUID_BLOOD ???
7149 return false;
7150 }
7151
7152 bool IsNVG()
7153 {
7154 return false;
7155 }
7156
7159 bool IsExplosive()
7160 {
7161 return false;
7162 }
7163
7165 {
7166 return "";
7167 }
7168
7170
7171 bool IsLightSource()
7172 {
7173 return false;
7174 }
7175
7177 {
7178 return true;
7179 }
7180
7181 //--- ACTION CONDITIONS
7182 //direction
7183 bool IsFacingPlayer(PlayerBase player, string selection)
7184 {
7185 return true;
7186 }
7187
7188 bool IsPlayerInside(PlayerBase player, string selection)
7189 {
7190 return true;
7191 }
7192
7193 override bool CanObstruct()
7194 {
7195 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
7196 return !player || !IsPlayerInside(player, "");
7197 }
7198
7199 override bool IsBeingPlaced()
7200 {
7201 return m_IsBeingPlaced;
7202 }
7203
7204 void SetIsBeingPlaced(bool is_being_placed)
7205 {
7206 m_IsBeingPlaced = is_being_placed;
7207 if (!is_being_placed)
7209 SetSynchDirty();
7210 }
7211
7212 //server-side
7213 void OnEndPlacement() {}
7214
7215 override bool IsHologram()
7216 {
7217 return m_IsHologram;
7218 }
7219
7220 bool CanBeDigged()
7221 {
7222 return m_CanBeDigged;
7223 }
7224
7226 {
7227 return 1;
7228 }
7229
7230 bool CanMakeGardenplot()
7231 {
7232 return false;
7233 }
7234
7235 void SetIsHologram(bool is_hologram)
7236 {
7237 m_IsHologram = is_hologram;
7238 SetSynchDirty();
7239 }
7240 /*
7241 protected float GetNutritionalEnergy()
7242 {
7243 Edible_Base edible = Edible_Base.Cast(this);
7244 return edible.GetFoodEnergy();
7245 }
7246
7247 protected float GetNutritionalWaterContent()
7248 {
7249 Edible_Base edible = Edible_Base.Cast(this);
7250 return edible.GetFoodWater();
7251 }
7252
7253 protected float GetNutritionalIndex()
7254 {
7255 Edible_Base edible = Edible_Base.Cast(this);
7256 return edible.GetFoodNutritionalIndex();
7257 }
7258
7259 protected float GetNutritionalFullnessIndex()
7260 {
7261 Edible_Base edible = Edible_Base.Cast(this);
7262 return edible.GetFoodTotalVolume();
7263 }
7264
7265 protected float GetNutritionalToxicity()
7266 {
7267 Edible_Base edible = Edible_Base.Cast(this);
7268 return edible.GetFoodToxicity();
7269
7270 }
7271 */
7272
7273
7274 // -------------------------------------------------------------------------
7275 override void OnMovedInsideCargo(EntityAI container)
7276 {
7277 super.OnMovedInsideCargo(container);
7278
7279 MiscGameplayFunctions.RemoveAllAttachedChildrenByTypename(this, {Bolt_Base});
7280 }
7281
7282 override void EEItemLocationChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
7283 {
7284 super.EEItemLocationChanged(oldLoc,newLoc);
7285
7286 PlayerBase new_player = null;
7287 PlayerBase old_player = null;
7288
7289 if (newLoc.GetParent())
7290 new_player = PlayerBase.Cast(newLoc.GetParent().GetHierarchyRootPlayer());
7291
7292 if (oldLoc.GetParent())
7293 old_player = PlayerBase.Cast(oldLoc.GetParent().GetHierarchyRootPlayer());
7294
7295 if (old_player && oldLoc.GetType() == InventoryLocationType.HANDS)
7296 {
7297 int r_index = old_player.GetHumanInventory().FindUserReservedLocationIndex(this);
7298
7299 if (r_index >= 0)
7300 {
7301 InventoryLocation r_il = new InventoryLocation;
7302 old_player.GetHumanInventory().GetUserReservedLocation(r_index,r_il);
7303
7304 old_player.GetHumanInventory().ClearUserReservedLocationAtIndex(r_index);
7305 int r_type = r_il.GetType();
7306 if (r_type == InventoryLocationType.CARGO || r_type == InventoryLocationType.PROXYCARGO)
7307 {
7308 r_il.GetParent().GetOnReleaseLock().Invoke(this);
7309 }
7310 else if (r_type == InventoryLocationType.ATTACHMENT)
7311 {
7312 r_il.GetParent().GetOnAttachmentReleaseLock().Invoke(this, r_il.GetSlot());
7313 }
7314
7315 }
7316 }
7317
7318 if (newLoc.GetType() == InventoryLocationType.HANDS)
7319 {
7320 if (new_player)
7321 new_player.ForceStandUpForHeavyItems(newLoc.GetItem());
7322
7323 if (new_player == old_player)
7324 {
7325
7326 if (oldLoc.GetParent() && new_player.GetHumanInventory().LocationGetEntity(oldLoc) == NULL)
7327 {
7328 if (oldLoc.GetType() == InventoryLocationType.CARGO)
7329 {
7330 if (oldLoc.GetParent().GetInventory().TestAddEntityInCargoExLoc(oldLoc, false, false, false, true, false, false))
7331 {
7332 new_player.GetHumanInventory().SetUserReservedLocation(this,oldLoc);
7333 }
7334 }
7335 else
7336 {
7337 new_player.GetHumanInventory().SetUserReservedLocation(this,oldLoc);
7338 }
7339 }
7340
7341 if (new_player.GetHumanInventory().FindUserReservedLocationIndex(this) >= 0)
7342 {
7343 int type = oldLoc.GetType();
7344 if (type == InventoryLocationType.CARGO || type == InventoryLocationType.PROXYCARGO)
7345 {
7346 oldLoc.GetParent().GetOnSetLock().Invoke(this);
7347 }
7348 else if (type == InventoryLocationType.ATTACHMENT)
7349 {
7350 oldLoc.GetParent().GetOnAttachmentSetLock().Invoke(this, oldLoc.GetSlot());
7351 }
7352 }
7353 if (!m_OldLocation)
7354 {
7355 m_OldLocation = new InventoryLocation;
7356 }
7357 m_OldLocation.Copy(oldLoc);
7358 }
7359 else
7360 {
7361 if (m_OldLocation)
7362 {
7363 m_OldLocation.Reset();
7364 }
7365 }
7366
7368 }
7369 else
7370 {
7371 if (new_player)
7372 {
7373 int res_index = new_player.GetHumanInventory().FindCollidingUserReservedLocationIndex(this, newLoc);
7374 if (res_index >= 0)
7375 {
7376 InventoryLocation il = new InventoryLocation;
7377 new_player.GetHumanInventory().GetUserReservedLocation(res_index,il);
7378 ItemBase it = ItemBase.Cast(il.GetItem());
7379 new_player.GetHumanInventory().ClearUserReservedLocationAtIndex(res_index);
7380 int rel_type = il.GetType();
7381 if (rel_type == InventoryLocationType.CARGO || rel_type == InventoryLocationType.PROXYCARGO)
7382 {
7383 il.GetParent().GetOnReleaseLock().Invoke(it);
7384 }
7385 else if (rel_type == InventoryLocationType.ATTACHMENT)
7386 {
7387 il.GetParent().GetOnAttachmentReleaseLock().Invoke(it, il.GetSlot());
7388 }
7389 //it.GetOnReleaseLock().Invoke(it);
7390 }
7391 }
7392 else if (old_player && newLoc.GetType() == InventoryLocationType.GROUND && m_ThrowItemOnDrop)
7393 {
7394 //ThrowPhysically(old_player, vector.Zero);
7395 m_ThrowItemOnDrop = false;
7396 }
7397
7398 if (m_OldLocation)
7399 {
7400 m_OldLocation.Reset();
7401 }
7402 }
7403 }
7404
7405 override void EOnContact(IEntity other, Contact extra)
7406 {
7408 {
7409 int liquidType = -1;
7410 float impactSpeed = ProcessImpactSoundEx(other, extra, m_ConfigWeight, m_ImpactSoundSurfaceHash, liquidType);
7411 if (impactSpeed > 0.0)
7412 {
7413 m_ImpactSpeed = impactSpeed;
7414 #ifndef SERVER
7415 PlayImpactSound(m_ConfigWeight, m_ImpactSpeed, m_ImpactSoundSurfaceHash);
7416 #else
7417 m_WantPlayImpactSound = true;
7418 SetSynchDirty();
7419 #endif
7420 m_CanPlayImpactSound = (liquidType == -1);// prevents further playing of the sound when the surface is a liquid type
7421 }
7422 }
7423
7424 #ifdef SERVER
7425 if (GetCompEM() && GetCompEM().IsPlugged())
7426 {
7427 if (GetCompEM().GetCordLength() < vector.Distance(GetPosition(), GetCompEM().GetEnergySource().GetPosition()))
7428 GetCompEM().UnplugThis();
7429 }
7430 #endif
7431 }
7432
7433 void RefreshPhysics();
7434
7435 override void OnCreatePhysics()
7436 {
7438 }
7439
7440 override void OnItemAttachmentSlotChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
7441 {
7442
7443 }
7444 // -------------------------------------------------------------------------
7445 override void OnItemLocationChanged(EntityAI old_owner, EntityAI new_owner)
7446 {
7447 super.OnItemLocationChanged(old_owner, new_owner);
7448
7449 PlayerBase relatedPlayer = PlayerBase.Cast(old_owner);
7450 PlayerBase playerNew = PlayerBase.Cast(new_owner);
7451
7452 if (!relatedPlayer && playerNew)
7453 relatedPlayer = playerNew;
7454
7455 if (relatedPlayer && relatedPlayer.GetPerformedActionID() != -1)
7456 {
7457 ActionManagerBase actionMgr = relatedPlayer.GetActionManager();
7458 if (actionMgr)
7459 {
7460 ActionBase currentAction = actionMgr.GetRunningAction();
7461 if (currentAction)
7462 currentAction.OnItemLocationChanged(this);
7463 }
7464 }
7465
7466 Man ownerPlayerOld = null;
7467 Man ownerPlayerNew = null;
7468
7469 if (old_owner)
7470 {
7471 if (old_owner.IsMan())
7472 {
7473 ownerPlayerOld = Man.Cast(old_owner);
7474 }
7475 else
7476 {
7477 ownerPlayerOld = Man.Cast(old_owner.GetHierarchyRootPlayer());
7478 }
7479 }
7480 else
7481 {
7482 if (new_owner && IsElectricAppliance() && GetCompEM() && GetCompEM().IsPlugged())
7483 {
7484 ActionBase action = ActionManagerBase.GetAction(ActionRepositionPluggedItem);
7485
7486 if (!action || !playerNew || playerNew.GetPerformedActionID() != action.GetID())
7487 {
7488 GetCompEM().UnplugThis();
7489 }
7490 }
7491 }
7492
7493 if (new_owner)
7494 {
7495 if (new_owner.IsMan())
7496 {
7497 ownerPlayerNew = Man.Cast(new_owner);
7498 }
7499 else
7500 {
7501 ownerPlayerNew = Man.Cast(new_owner.GetHierarchyRootPlayer());
7502 }
7503 }
7504
7505 if (ownerPlayerOld != ownerPlayerNew)
7506 {
7507 if (ownerPlayerOld)
7508 {
7509 array<EntityAI> subItemsExit = new array<EntityAI>;
7510 GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER,subItemsExit);
7511 for (int i = 0; i < subItemsExit.Count(); i++)
7512 {
7513 ItemBase itemExit = ItemBase.Cast(subItemsExit.Get(i));
7514 itemExit.OnInventoryExit(ownerPlayerOld);
7515 }
7516 }
7517
7518 if (ownerPlayerNew)
7519 {
7520 array<EntityAI> subItemsEnter = new array<EntityAI>;
7521 GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER,subItemsEnter);
7522 for (int j = 0; j < subItemsEnter.Count(); j++)
7523 {
7524 ItemBase itemEnter = ItemBase.Cast(subItemsEnter.Get(j));
7525 itemEnter.OnInventoryEnter(ownerPlayerNew);
7526 }
7527 }
7528 }
7529 else if (ownerPlayerNew != null)
7530 {
7531 PlayerBase nplayer;
7532 if (PlayerBase.CastTo(nplayer, ownerPlayerNew))
7533 {
7534 array<EntityAI> subItemsUpdate = new array<EntityAI>;
7535 GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER,subItemsUpdate);
7536 for (int k = 0; k < subItemsUpdate.Count(); k++)
7537 {
7538 ItemBase itemUpdate = ItemBase.Cast(subItemsUpdate.Get(k));
7539 itemUpdate.UpdateQuickbarShortcutVisibility(nplayer);
7540 }
7541 }
7542 }
7543
7544 if (old_owner)
7545 old_owner.OnChildItemRemoved(this);
7546 if (new_owner)
7547 new_owner.OnChildItemReceived(this);
7548 }
7549
7550 // -------------------------------------------------------------------------------
7551 override void EEDelete(EntityAI parent)
7552 {
7553 super.EEDelete(parent);
7554 PlayerBase player = PlayerBase.Cast(GetHierarchyRootPlayer());
7555 if (player)
7556 {
7557 OnInventoryExit(player);
7558
7559 if (player.IsAlive())
7560 {
7561 int r_index = player.GetHumanInventory().FindUserReservedLocationIndex(this);
7562 if (r_index >= 0)
7563 {
7564 InventoryLocation r_il = new InventoryLocation;
7565 player.GetHumanInventory().GetUserReservedLocation(r_index,r_il);
7566
7567 player.GetHumanInventory().ClearUserReservedLocationAtIndex(r_index);
7568 int r_type = r_il.GetType();
7569 if (r_type == InventoryLocationType.CARGO || r_type == InventoryLocationType.PROXYCARGO)
7570 {
7571 r_il.GetParent().GetOnReleaseLock().Invoke(this);
7572 }
7573 else if (r_type == InventoryLocationType.ATTACHMENT)
7574 {
7575 r_il.GetParent().GetOnAttachmentReleaseLock().Invoke(this, r_il.GetSlot());
7576 }
7577
7578 }
7579
7580 player.RemoveQuickBarEntityShortcut(this);
7581 }
7582 }
7583 }
7584 // -------------------------------------------------------------------------------
7585 override void EEKilled(Object killer)
7586 {
7587 super.EEKilled(killer);
7588
7590 if (killer && killer.IsFireplace() && CanExplodeInFire())
7591 {
7592 if (GetTemperature() >= GameConstants.ITEM_TEMPERATURE_TO_EXPLODE_MIN)
7593 {
7594 if (IsMagazine())
7595 {
7596 if (Magazine.Cast(this).GetAmmoCount() > 0)
7597 {
7598 ExplodeAmmo();
7599 }
7600 }
7601 else
7602 {
7603 Explode(DamageType.EXPLOSION);
7604 }
7605 }
7606 }
7607 }
7608
7609 override void OnWasAttached(EntityAI parent, int slot_id)
7610 {
7611 MiscGameplayFunctions.RemoveAllAttachedChildrenByTypename(this, {Bolt_Base});
7612
7613 super.OnWasAttached(parent, slot_id);
7614
7615 if (HasQuantity())
7616 UpdateNetSyncVariableFloat("m_VarQuantity", GetQuantityMin(), m_VarQuantityMax);
7617
7618 PlayAttachSound(InventorySlots.GetSlotName(slot_id));
7619 }
7620
7621 override void OnWasDetached(EntityAI parent, int slot_id)
7622 {
7623 super.OnWasDetached(parent, slot_id);
7624
7625 if (HasQuantity())
7626 UpdateNetSyncVariableFloat("m_VarQuantity", GetQuantityMin(), m_VarQuantityMax);
7627 }
7628
7629 override string ChangeIntoOnAttach(string slot)
7630 {
7631 int idx;
7632 TStringArray inventory_slots = new TStringArray;
7633 TStringArray attach_types = new TStringArray;
7634
7635 ConfigGetTextArray("ChangeInventorySlot",inventory_slots);
7636 if (inventory_slots.Count() < 1) //is string
7637 {
7638 inventory_slots.Insert(ConfigGetString("ChangeInventorySlot"));
7639 attach_types.Insert(ConfigGetString("ChangeIntoOnAttach"));
7640 }
7641 else //is array
7642 {
7643 ConfigGetTextArray("ChangeIntoOnAttach",attach_types);
7644 }
7645
7646 idx = inventory_slots.Find(slot);
7647 if (idx < 0)
7648 return "";
7649
7650 return attach_types.Get(idx);
7651 }
7652
7653 override string ChangeIntoOnDetach()
7654 {
7655 int idx = -1;
7656 string slot;
7657
7658 TStringArray inventory_slots = new TStringArray;
7659 TStringArray detach_types = new TStringArray;
7660
7661 this.ConfigGetTextArray("ChangeInventorySlot",inventory_slots);
7662 if (inventory_slots.Count() < 1) //is string
7663 {
7664 inventory_slots.Insert(this.ConfigGetString("ChangeInventorySlot"));
7665 detach_types.Insert(this.ConfigGetString("ChangeIntoOnDetach"));
7666 }
7667 else //is array
7668 {
7669 this.ConfigGetTextArray("ChangeIntoOnDetach",detach_types);
7670 if (detach_types.Count() < 1)
7671 detach_types.Insert(this.ConfigGetString("ChangeIntoOnDetach"));
7672 }
7673
7674 for (int i = 0; i < inventory_slots.Count(); i++)
7675 {
7676 slot = inventory_slots.Get(i);
7677 }
7678
7679 if (slot != "")
7680 {
7681 if (detach_types.Count() == 1)
7682 idx = 0;
7683 else
7684 idx = inventory_slots.Find(slot);
7685 }
7686 if (idx < 0)
7687 return "";
7688
7689 return detach_types.Get(idx);
7690 }
7691
7692 void ExplodeAmmo()
7693 {
7694 //timer
7695 ref Timer explode_timer = new Timer(CALL_CATEGORY_SYSTEM);
7696
7697 //min/max time
7698 float min_time = 1;
7699 float max_time = 3;
7700 float delay = Math.RandomFloat(min_time, max_time);
7701
7702 explode_timer.Run(delay, this, "DoAmmoExplosion");
7703 }
7704
7705 void DoAmmoExplosion()
7706 {
7707 Magazine magazine = Magazine.Cast(this);
7708 int pop_sounds_count = 6;
7709 string pop_sounds[ 6 ] = { "ammopops_1","ammopops_2","ammopops_3","ammopops_4","ammopops_5","ammopops_6" };
7710
7711 //play sound
7712 int sound_idx = Math.RandomInt(0, pop_sounds_count - 1);
7713 string sound_name = pop_sounds[ sound_idx ];
7714 GetGame().CreateSoundOnObject(this, sound_name, 20, false);
7715
7716 //remove ammo count
7717 magazine.ServerAddAmmoCount(-1);
7718
7719 //if condition then repeat -> ExplodeAmmo
7720 float min_temp_to_explode = 100; //min temperature for item to explode
7721
7722 if (magazine.GetAmmoCount() > 0 && GetTemperature() >= min_temp_to_explode) //TODO ? add check for parent -> fireplace
7723 {
7724 ExplodeAmmo();
7725 }
7726 }
7727
7728 // -------------------------------------------------------------------------------
7729 override void EEHitBy(TotalDamageResult damageResult, int damageType, EntityAI source, int component, string dmgZone, string ammo, vector modelPos, float speedCoef)
7730 {
7731 super.EEHitBy(damageResult, damageType, source, component, dmgZone, ammo, modelPos, speedCoef);
7732
7733 const int CHANCE_DAMAGE_CARGO = 4;
7734 const int CHANCE_DAMAGE_ATTACHMENT = 1;
7735 const int CHANCE_DAMAGE_NOTHING = 2;
7736
7737 if (IsClothing() || IsContainer() || IsItemTent())
7738 {
7739 float dmg = damageResult.GetDamage("","Health") * -0.5;
7740 int chances;
7741 int rnd;
7742
7743 if (GetInventory().GetCargo())
7744 {
7745 chances = CHANCE_DAMAGE_CARGO + CHANCE_DAMAGE_ATTACHMENT + CHANCE_DAMAGE_NOTHING;
7746 rnd = Math.RandomInt(0,chances);
7747
7748 if (rnd < CHANCE_DAMAGE_CARGO)
7749 {
7750 DamageItemInCargo(dmg);
7751 }
7752 else if (rnd < (chances - CHANCE_DAMAGE_NOTHING))
7753 {
7755 }
7756 }
7757 else
7758 {
7759 chances = CHANCE_DAMAGE_ATTACHMENT + CHANCE_DAMAGE_NOTHING;
7760 rnd = Math.RandomInt(0,chances);
7761
7762 if (rnd < CHANCE_DAMAGE_ATTACHMENT)
7763 {
7765 }
7766 }
7767 }
7768 }
7769
7770 bool DamageItemInCargo(float damage)
7771 {
7772 if (GetInventory().GetCargo())
7773 {
7774 int item_count = GetInventory().GetCargo().GetItemCount();
7775 if (item_count > 0)
7776 {
7777 int random_pick = Math.RandomInt(0, item_count);
7778 ItemBase item = ItemBase.Cast(GetInventory().GetCargo().GetItem(random_pick));
7779 if (!item.IsExplosive())
7780 {
7781 item.AddHealth("","",damage);
7782 return true;
7783 }
7784 }
7785 }
7786 return false;
7787 }
7788
7789 bool DamageItemAttachments(float damage)
7790 {
7791 int attachment_count = GetInventory().AttachmentCount();
7792 if (attachment_count > 0)
7793 {
7794 int random_pick = Math.RandomInt(0, attachment_count);
7795 ItemBase attachment = ItemBase.Cast(GetInventory().GetAttachmentFromIndex(random_pick));
7796 if (!attachment.IsExplosive())
7797 {
7798 attachment.AddHealth("","",damage);
7799 return true;
7800 }
7801 }
7802 return false;
7803 }
7804
7805 override bool IsSplitable()
7806 {
7807 return m_CanThisBeSplit;
7808 }
7809 //----------------
7810 override bool CanBeSplit()
7811 {
7812 if (IsSplitable() && (GetQuantity() > 1))
7813 return GetInventory().CanRemoveEntity();
7814
7815 return false;
7816 }
7817
7818 protected bool ShouldSplitQuantity(float quantity)
7819 {
7820 // don't call 'CanBeSplit' here, too strict and will introduce a freeze-crash when dismantling fence with a fireplace nearby
7821 if (!IsSplitable())
7822 return false;
7823
7824 // nothing to split?
7825 if (GetQuantity() <= 1)
7826 return false;
7827
7828 // check if we should re-use the item instead of creating a new copy?
7829 // implicit cast to int, if 'IsSplitable' returns true, these values are assumed ints
7830 int delta = GetQuantity() - quantity;
7831 if (delta == 0)
7832 return false;
7833
7834 // valid to split
7835 return true;
7836 }
7837
7838 override void SplitIntoStackMaxClient(EntityAI destination_entity, int slot_id )
7839 {
7840 if (GetGame().IsClient())
7841 {
7842 if (ScriptInputUserData.CanStoreInputUserData())
7843 {
7844 ScriptInputUserData ctx = new ScriptInputUserData;
7846 ctx.Write(1);
7847 ItemBase i1 = this; // @NOTE: workaround for correct serialization
7848 ctx.Write(i1);
7849 ctx.Write(destination_entity);
7850 ctx.Write(true);
7851 ctx.Write(slot_id);
7852 ctx.Send();
7853 }
7854 }
7855 else if (!GetGame().IsMultiplayer())
7856 {
7857 SplitIntoStackMax(destination_entity, slot_id, PlayerBase.Cast(GetGame().GetPlayer()));
7858 }
7859 }
7860
7861 void SplitIntoStackMax(EntityAI destination_entity, int slot_id, PlayerBase player)
7862 {
7863 float split_quantity_new;
7864 ItemBase new_item;
7865 float quantity = GetQuantity();
7866 float stack_max = GetTargetQuantityMax(slot_id);
7867 InventoryLocation loc = new InventoryLocation;
7868
7869 if (destination_entity && slot_id != -1 && InventorySlots.IsSlotIdValid(slot_id))
7870 {
7871 if (stack_max <= GetQuantity())
7872 split_quantity_new = stack_max;
7873 else
7874 split_quantity_new = GetQuantity();
7875
7876 if (ShouldSplitQuantity(split_quantity_new))
7877 {
7878 new_item = ItemBase.Cast(destination_entity.GetInventory().CreateAttachmentEx(this.GetType(), slot_id));
7879 if (new_item)
7880 {
7881 new_item.SetResultOfSplit(true);
7882 MiscGameplayFunctions.TransferItemProperties(this, new_item);
7883 AddQuantity(-split_quantity_new, false, true);
7884 new_item.SetQuantity(split_quantity_new, false, true);
7885 }
7886 }
7887 }
7888 else if (destination_entity && slot_id == -1)
7889 {
7890 if (quantity > stack_max)
7891 split_quantity_new = stack_max;
7892 else
7893 split_quantity_new = quantity;
7894
7895 if (ShouldSplitQuantity(split_quantity_new))
7896 {
7897 if (destination_entity.GetInventory().FindFreeLocationFor(this, FindInventoryLocationType.ANY, loc))
7898 {
7899 Object o = destination_entity.GetInventory().LocationCreateEntity(loc, GetType(), ECE_IN_INVENTORY, RF_DEFAULT);
7900 new_item = ItemBase.Cast(o);
7901 }
7902
7903 if (new_item)
7904 {
7905 new_item.SetResultOfSplit(true);
7906 MiscGameplayFunctions.TransferItemProperties(this, new_item);
7907 AddQuantity(-split_quantity_new, false, true);
7908 new_item.SetQuantity(split_quantity_new, false, true);
7909 }
7910 }
7911 }
7912 else
7913 {
7914 if (stack_max != 0)
7915 {
7916 if (stack_max < GetQuantity())
7917 {
7918 split_quantity_new = GetQuantity() - stack_max;
7919 }
7920
7921 if (split_quantity_new == 0)
7922 {
7923 if (!GetGame().IsMultiplayer())
7924 player.PhysicalPredictiveDropItem(this);
7925 else
7926 player.ServerDropEntity(this);
7927 return;
7928 }
7929
7930 if (ShouldSplitQuantity(split_quantity_new))
7931 {
7932 new_item = ItemBase.Cast(GetGame().CreateObjectEx(GetType(), player.GetWorldPosition(), ECE_PLACE_ON_SURFACE));
7933
7934 if (new_item)
7935 {
7936 new_item.SetResultOfSplit(true);
7937 MiscGameplayFunctions.TransferItemProperties(this, new_item);
7938 SetQuantity(split_quantity_new, false, true);
7939 new_item.SetQuantity(stack_max, false, true);
7940 new_item.PlaceOnSurface();
7941 }
7942 }
7943 }
7944 }
7945 }
7946
7947 override void SplitIntoStackMaxEx(EntityAI destination_entity, int slot_id)
7948 {
7949 float split_quantity_new;
7950 ItemBase new_item;
7951 float quantity = GetQuantity();
7952 float stack_max = GetTargetQuantityMax(slot_id);
7953 InventoryLocation loc = new InventoryLocation;
7954
7955 if (destination_entity && slot_id != -1 && InventorySlots.IsSlotIdValid(slot_id))
7956 {
7957 if (stack_max <= GetQuantity())
7958 split_quantity_new = stack_max;
7959 else
7960 split_quantity_new = GetQuantity();
7961
7962 if (ShouldSplitQuantity(split_quantity_new))
7963 {
7964 new_item = ItemBase.Cast(destination_entity.GetInventory().CreateAttachmentEx(this.GetType(), slot_id));
7965 if (new_item)
7966 {
7967 new_item.SetResultOfSplit(true);
7968 MiscGameplayFunctions.TransferItemProperties(this, new_item);
7969 AddQuantity(-split_quantity_new, false, true);
7970 new_item.SetQuantity(split_quantity_new, false, true);
7971 }
7972 }
7973 }
7974 else if (destination_entity && slot_id == -1)
7975 {
7976 if (quantity > stack_max)
7977 split_quantity_new = stack_max;
7978 else
7979 split_quantity_new = quantity;
7980
7981 if (ShouldSplitQuantity(split_quantity_new))
7982 {
7983 if (destination_entity.GetInventory().FindFreeLocationFor(this, FindInventoryLocationType.ANY, loc))
7984 {
7985 Object o = destination_entity.GetInventory().LocationCreateEntity(loc, GetType(), ECE_IN_INVENTORY, RF_DEFAULT);
7986 new_item = ItemBase.Cast(o);
7987 }
7988
7989 if (new_item)
7990 {
7991 new_item.SetResultOfSplit(true);
7992 MiscGameplayFunctions.TransferItemProperties(this, new_item);
7993 AddQuantity(-split_quantity_new, false, true);
7994 new_item.SetQuantity(split_quantity_new, false, true);
7995 }
7996 }
7997 }
7998 else
7999 {
8000 if (stack_max != 0)
8001 {
8002 if (stack_max < GetQuantity())
8003 {
8004 split_quantity_new = GetQuantity() - stack_max;
8005 }
8006
8007 if (ShouldSplitQuantity(split_quantity_new))
8008 {
8009 new_item = ItemBase.Cast(GetGame().CreateObjectEx(GetType(),GetWorldPosition(), ECE_PLACE_ON_SURFACE));
8010
8011 if (new_item)
8012 {
8013 new_item.SetResultOfSplit(true);
8014 MiscGameplayFunctions.TransferItemProperties(this, new_item);
8015 SetQuantity(split_quantity_new, false, true);
8016 new_item.SetQuantity(stack_max, false, true);
8017 new_item.PlaceOnSurface();
8018 }
8019 }
8020 }
8021 }
8022 }
8023
8024 void SplitIntoStackMaxToInventoryLocationClient(notnull InventoryLocation dst)
8025 {
8026 if (GetGame().IsClient())
8027 {
8028 if (ScriptInputUserData.CanStoreInputUserData())
8029 {
8030 ScriptInputUserData ctx = new ScriptInputUserData;
8032 ctx.Write(4);
8033 ItemBase thiz = this; // @NOTE: workaround for correct serialization
8034 ctx.Write(thiz);
8035 dst.WriteToContext(ctx);
8036 ctx.Send();
8037 }
8038 }
8039 else if (!GetGame().IsMultiplayer())
8040 {
8042 }
8043 }
8044
8045 void SplitIntoStackMaxCargoClient(EntityAI destination_entity, int idx, int row, int col)
8046 {
8047 if (GetGame().IsClient())
8048 {
8049 if (ScriptInputUserData.CanStoreInputUserData())
8050 {
8051 ScriptInputUserData ctx = new ScriptInputUserData;
8053 ctx.Write(2);
8054 ItemBase dummy = this; // @NOTE: workaround for correct serialization
8055 ctx.Write(dummy);
8056 ctx.Write(destination_entity);
8057 ctx.Write(true);
8058 ctx.Write(idx);
8059 ctx.Write(row);
8060 ctx.Write(col);
8061 ctx.Send();
8062 }
8063 }
8064 else if (!GetGame().IsMultiplayer())
8065 {
8066 SplitIntoStackMaxCargo(destination_entity, idx, row, col);
8067 }
8068 }
8069
8070 void SplitIntoStackMaxToInventoryLocation(notnull InventoryLocation dst)
8071 {
8073 }
8074
8075 ItemBase SplitIntoStackMaxToInventoryLocationEx(notnull InventoryLocation dst)
8076 {
8077 float quantity = GetQuantity();
8078 float split_quantity_new;
8079 ItemBase new_item;
8080 if (dst.IsValid())
8081 {
8082 int slot_id = dst.GetSlot();
8083 float stack_max = GetTargetQuantityMax(slot_id);
8084
8085 if (quantity > stack_max)
8086 split_quantity_new = stack_max;
8087 else
8088 split_quantity_new = quantity;
8089
8090 if (ShouldSplitQuantity(split_quantity_new))
8091 {
8092 new_item = ItemBase.Cast(GameInventory.LocationCreateEntity(dst, this.GetType(), ECE_IN_INVENTORY, RF_DEFAULT));
8093
8094 if (new_item)
8095 {
8096 new_item.SetResultOfSplit(true);
8097 MiscGameplayFunctions.TransferItemProperties(this,new_item);
8098 AddQuantity(-split_quantity_new, false, true);
8099 new_item.SetQuantity(split_quantity_new, false, true);
8100 }
8101
8102 return new_item;
8103 }
8104 }
8105
8106 return null;
8107 }
8108
8109 void SplitIntoStackMaxCargo(EntityAI destination_entity, int idx, int row, int col)
8110 {
8111 float quantity = GetQuantity();
8112 float split_quantity_new;
8113 ItemBase new_item;
8114 if (destination_entity)
8115 {
8116 float stackable = GetTargetQuantityMax();
8117 if (quantity > stackable)
8118 split_quantity_new = stackable;
8119 else
8120 split_quantity_new = quantity;
8121
8122 if (ShouldSplitQuantity(split_quantity_new))
8123 {
8124 new_item = ItemBase.Cast(destination_entity.GetInventory().CreateEntityInCargoEx(this.GetType(), idx, row, col, false));
8125 if (new_item)
8126 {
8127 new_item.SetResultOfSplit(true);
8128 MiscGameplayFunctions.TransferItemProperties(this,new_item);
8129 AddQuantity(-split_quantity_new, false, true);
8130 new_item.SetQuantity(split_quantity_new, false, true);
8131 }
8132 }
8133 }
8134 }
8135
8136 void SplitIntoStackMaxHandsClient(PlayerBase player)
8137 {
8138 if (GetGame().IsClient())
8139 {
8140 if (ScriptInputUserData.CanStoreInputUserData())
8141 {
8142 ScriptInputUserData ctx = new ScriptInputUserData;
8144 ctx.Write(3);
8145 ItemBase i1 = this; // @NOTE: workaround for correct serialization
8146 ctx.Write(i1);
8147 ItemBase destination_entity = this;
8148 ctx.Write(destination_entity);
8149 ctx.Write(true);
8150 ctx.Write(0);
8151 ctx.Send();
8152 }
8153 }
8154 else if (!GetGame().IsMultiplayer())
8155 {
8156 SplitIntoStackMaxHands(player);
8157 }
8158 }
8159
8160 void SplitIntoStackMaxHands(PlayerBase player)
8161 {
8162 float quantity = GetQuantity();
8163 float split_quantity_new;
8164 ref ItemBase new_item;
8165 if (player)
8166 {
8167 float stackable = GetTargetQuantityMax();
8168 if (quantity > stackable)
8169 split_quantity_new = stackable;
8170 else
8171 split_quantity_new = quantity;
8172
8173 if (ShouldSplitQuantity(split_quantity_new))
8174 {
8175 EntityAI in_hands = player.GetHumanInventory().CreateInHands(this.GetType());
8176 new_item = ItemBase.Cast(in_hands);
8177 if (new_item)
8178 {
8179 new_item.SetResultOfSplit(true);
8180 MiscGameplayFunctions.TransferItemProperties(this,new_item);
8181 AddQuantity(-split_quantity_new, false, true);
8182 new_item.SetQuantity(split_quantity_new, false, true);
8183 }
8184 }
8185 }
8186 }
8187
8188 void SplitItemToInventoryLocation(notnull InventoryLocation dst)
8189 {
8190 float quantity = GetQuantity();
8191 float split_quantity_new = Math.Floor(quantity * 0.5);
8192
8193 if (!ShouldSplitQuantity(split_quantity_new))
8194 return;
8195
8196 ItemBase new_item = ItemBase.Cast(GameInventory.LocationCreateEntity(dst, GetType(), ECE_IN_INVENTORY, RF_DEFAULT));
8197
8198 if (new_item)
8199 {
8200 if (new_item.GetQuantityMax() < split_quantity_new)
8201 {
8202 split_quantity_new = new_item.GetQuantityMax();
8203 }
8204
8205 new_item.SetResultOfSplit(true);
8206 MiscGameplayFunctions.TransferItemProperties(this, new_item);
8207
8208 if (dst.IsValid() && dst.GetType() == InventoryLocationType.ATTACHMENT && split_quantity_new > 1)
8209 {
8210 AddQuantity(-1, false, true);
8211 new_item.SetQuantity(1, false, true);
8212 }
8213 else
8214 {
8215 AddQuantity(-split_quantity_new, false, true);
8216 new_item.SetQuantity(split_quantity_new, false, true);
8217 }
8218 }
8219 }
8220
8221 void SplitItem(PlayerBase player)
8222 {
8223 float quantity = GetQuantity();
8224 float split_quantity_new = Math.Floor(quantity / 2);
8225
8226 if (!ShouldSplitQuantity(split_quantity_new))
8227 return;
8228
8229 InventoryLocation invloc = new InventoryLocation;
8230 bool found = player.GetInventory().FindFirstFreeLocationForNewEntity(GetType(), FindInventoryLocationType.ATTACHMENT, invloc);
8231
8232 ItemBase new_item;
8233 new_item = player.CreateCopyOfItemInInventoryOrGroundEx(this, true);
8234
8235 if (new_item)
8236 {
8237 if (new_item.GetQuantityMax() < split_quantity_new)
8238 {
8239 split_quantity_new = new_item.GetQuantityMax();
8240 }
8241 if (found && invloc.IsValid() && invloc.GetType() == InventoryLocationType.ATTACHMENT && split_quantity_new > 1)
8242 {
8243 AddQuantity(-1, false, true);
8244 new_item.SetQuantity(1, false, true);
8245 }
8246 else if (split_quantity_new > 1)
8247 {
8248 AddQuantity(-split_quantity_new, false, true);
8249 new_item.SetQuantity(split_quantity_new, false, true);
8250 }
8251 }
8252 }
8253
8255 void OnQuantityChanged(float delta)
8256 {
8257 SetWeightDirty();
8258 ItemBase parent = ItemBase.Cast(GetHierarchyParent());
8259
8260 if (parent)
8261 parent.OnAttachmentQuantityChangedEx(this, delta);
8262
8263 if (IsLiquidContainer())
8264 {
8265 if (GetQuantityNormalized() <= 0.0)
8266 {
8268 }
8269 else if (GetLiquidType() == LIQUID_NONE)
8270 {
8271 ErrorEx("Undefined liquid type quantity changed, please define liquid type first! Using init value.",ErrorExSeverity.INFO);
8273 }
8274 }
8275
8276 }
8277
8280 {
8281 // insert code here
8282 }
8283
8285 void OnAttachmentQuantityChangedEx(ItemBase item , float delta)
8286 {
8288 }
8289
8290 override void EEHealthLevelChanged(int oldLevel, int newLevel, string zone)
8291 {
8292 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
8293
8294 if (GetGame().IsServer())
8295 {
8296 if (newLevel == GameConstants.STATE_RUINED)
8297 {
8299 EntityAI parent = GetHierarchyParent();
8300 if (parent && parent.IsFireplace())
8301 {
8302 CargoBase cargo = GetInventory().GetCargo();
8303 if (cargo)
8304 {
8305 for (int i = 0; i < cargo.GetItemCount(); ++i)
8306 {
8307 parent.GetInventory().TakeEntityToInventory(InventoryMode.SERVER, FindInventoryLocationType.CARGO, cargo.GetItem(i));
8308 }
8309 }
8310 }
8311 }
8312
8313 if (IsResultOfSplit())
8314 {
8315 // reset the splitting result flag, return to normal item behavior
8316 SetResultOfSplit(false);
8317 return;
8318 }
8319
8320 if (m_Cleanness != 0 && oldLevel < newLevel && newLevel != 0)
8321 {
8322 SetCleanness(0);//unclean the item upon damage dealt
8323 }
8324 }
8325 }
8326
8327 // just the split? TODO: verify
8328 override void OnRightClick()
8329 {
8330 super.OnRightClick();
8331
8332 if (CanBeSplit() && !GetDayZGame().IsLeftCtrlDown() && !GetGame().GetPlayer().GetInventory().HasInventoryReservation(this,null))
8333 {
8334 if (GetGame().IsClient())
8335 {
8336 if (ScriptInputUserData.CanStoreInputUserData())
8337 {
8338 EntityAI root = GetHierarchyRoot();
8339 Man playerOwner = GetHierarchyRootPlayer();
8340 InventoryLocation dst = new InventoryLocation;
8341
8342 // 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
8343 if (!playerOwner && root && root == this)
8344 {
8346 }
8347 else
8348 {
8349 // 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
8350 GetInventory().GetCurrentInventoryLocation(dst);
8351 if (!dst.GetParent() || dst.GetParent() && !dst.GetParent().GetInventory().FindFreeLocationFor(this, FindInventoryLocationType.CARGO, dst))
8352 {
8353 PlayerBase player = PlayerBase.Cast(GetGame().GetPlayer());
8354 if (!player.GetInventory().FindFreeLocationFor(this, FindInventoryLocationType.CARGO, dst) || !playerOwner)
8355 {
8357 }
8358 else
8359 {
8360 dst.SetCargo(dst.GetParent(), this, dst.GetIdx(), dst.GetRow(), dst.GetCol(), dst.GetFlip());
8361 /* hacky solution to check reservation of "this" item instead of null since the gamecode is checking null against null and returning reservation=true incorrectly
8362 this shouldnt cause issues within this scope*/
8363 if (GetGame().GetPlayer().GetInventory().HasInventoryReservation(this, dst))
8364 {
8366 }
8367 else
8368 {
8369 GetGame().GetPlayer().GetInventory().AddInventoryReservationEx(null, dst, GameInventory.c_InventoryReservationTimeoutShortMS);
8370 }
8371 }
8372 }
8373 }
8374
8375 ScriptInputUserData ctx = new ScriptInputUserData;
8377 ctx.Write(4);
8378 ItemBase thiz = this; // @NOTE: workaround for correct serialization
8379 ctx.Write(thiz);
8380 dst.WriteToContext(ctx);
8381 ctx.Write(true); // dummy
8382 ctx.Send();
8383 }
8384 }
8385 else if (!GetGame().IsMultiplayer())
8386 {
8387 SplitItem(PlayerBase.Cast(GetGame().GetPlayer()));
8388 }
8389 }
8390 }
8391
8392 protected void SetInventoryLocationToVicinityOrCurrent(EntityAI root, inout InventoryLocation dst)
8393 {
8394 if (root)
8395 {
8396 vector m4[4];
8397 root.GetTransform(m4);
8398 dst.SetGround(this, m4);
8399 }
8400 else
8401 {
8402 GetInventory().GetCurrentInventoryLocation(dst);
8403 }
8404 }
8405
8406 override bool CanBeCombined(EntityAI other_item, bool reservation_check = true, bool stack_max_limit = false)
8407 {
8408 //TODO: delete check zero quantity check after fix double posts hands fsm events
8409 if (!other_item || GetType() != other_item.GetType() || (IsFullQuantity() && other_item.GetQuantity() > 0) || other_item == this)
8410 return false;
8411
8412 if (GetHealthLevel() == GameConstants.STATE_RUINED || other_item.GetHealthLevel() == GameConstants.STATE_RUINED)
8413 return false;
8414
8415 //can_this_be_combined = ConfigGetBool("canBeSplit");
8417 return false;
8418
8419
8420 Magazine mag = Magazine.Cast(this);
8421 if (mag)
8422 {
8423 if (mag.GetAmmoCount() >= mag.GetAmmoMax())
8424 return false;
8425
8426 if (stack_max_limit)
8427 {
8428 Magazine other_mag = Magazine.Cast(other_item);
8429 if (other_item)
8430 {
8431 if (mag.GetAmmoCount() + other_mag.GetAmmoCount() > mag.GetAmmoMax())
8432 return false;
8433 }
8434
8435 }
8436 }
8437 else
8438 {
8439 //TODO: delete check zero quantity check after fix double posts hands fsm events
8440 if (GetQuantity() >= GetQuantityMax() && other_item.GetQuantity() > 0 )
8441 return false;
8442
8443 if (stack_max_limit && (GetQuantity() + other_item.GetQuantity() > GetQuantityMax()))
8444 return false;
8445 }
8446
8447 PlayerBase player = null;
8448 if (CastTo(player, GetHierarchyRootPlayer())) //false when attached to player's attachment slot
8449 {
8450 if (player.GetInventory().HasAttachment(this))
8451 return false;
8452
8453 if (player.IsItemsToDelete())
8454 return false;
8455 }
8456
8457 if (reservation_check && (GetInventory().HasInventoryReservation(this, null) || other_item.GetInventory().HasInventoryReservation(other_item, null)))
8458 return false;
8459
8460 int slotID;
8461 string slotName;
8462 if (GetInventory().GetCurrentAttachmentSlotInfo(slotID,slotName) && GetHierarchyParent().GetInventory().GetSlotLock(slotID))
8463 return false;
8464
8465 return true;
8466 }
8467
8468 bool IsCombineAll(ItemBase other_item, bool use_stack_max = false)
8469 {
8470 return ComputeQuantityUsed(other_item, use_stack_max) == other_item.GetQuantity();
8471 }
8472
8473 bool IsResultOfSplit()
8474 {
8475 return m_IsResultOfSplit;
8476 }
8477
8478 void SetResultOfSplit(bool value)
8479 {
8480 m_IsResultOfSplit = value;
8481 }
8482
8483 int ComputeQuantityUsed(ItemBase other_item, bool use_stack_max = true)
8484 {
8485 return ComputeQuantityUsedEx(other_item, use_stack_max);
8486 }
8487
8488 float ComputeQuantityUsedEx(ItemBase other_item, bool use_stack_max = true)
8489 {
8490 float other_item_quantity = other_item.GetQuantity();
8491 float this_free_space;
8492
8493 float stack_max = GetQuantityMax();
8494
8495 this_free_space = stack_max - GetQuantity();
8496
8497 if (other_item_quantity > this_free_space)
8498 {
8499 return this_free_space;
8500 }
8501 else
8502 {
8503 return other_item_quantity;
8504 }
8505 }
8506
8507 override void CombineItemsEx(EntityAI entity2, bool use_stack_max = true)
8508 {
8509 CombineItems(ItemBase.Cast(entity2),use_stack_max);
8510 }
8511
8512 void CombineItems(ItemBase other_item, bool use_stack_max = true)
8513 {
8514 if (!CanBeCombined(other_item, false))
8515 return;
8516
8517 if (!IsMagazine() && other_item)
8518 {
8519 float quantity_used = ComputeQuantityUsedEx(other_item,use_stack_max);
8520 if (quantity_used != 0)
8521 {
8522 float hp1 = GetHealth01("","");
8523 float hp2 = other_item.GetHealth01("","");
8524 float hpResult = ((hp1*GetQuantity()) + (hp2*quantity_used));
8525 hpResult = hpResult / (GetQuantity() + quantity_used);
8526
8527 hpResult *= GetMaxHealth();
8528 Math.Round(hpResult);
8529 SetHealth("", "Health", hpResult);
8530
8531 AddQuantity(quantity_used);
8532 other_item.AddQuantity(-quantity_used);
8533 }
8534 }
8535 OnCombine(other_item);
8536 }
8537
8538 void OnCombine(ItemBase other_item)
8539 {
8540 #ifdef SERVER
8541 if (!GetHierarchyRootPlayer() && GetHierarchyParent())
8542 GetHierarchyParent().IncreaseLifetimeUp();
8543 #endif
8544 };
8545
8546 void GetRecipesActions(Man player, out TSelectableActionInfoArray outputList)
8547 {
8548 PlayerBase p = PlayerBase.Cast(player);
8549
8550 array<int> recipesIds = p.m_Recipes;
8551 PluginRecipesManager moduleRecipesManager = PluginRecipesManager.Cast(GetPlugin(PluginRecipesManager));
8552 if (moduleRecipesManager)
8553 {
8554 EntityAI itemInHands = player.GetHumanInventory().GetEntityInHands();
8555 moduleRecipesManager.GetValidRecipes(ItemBase.Cast(this), ItemBase.Cast(itemInHands), recipesIds, p);
8556 }
8557
8558 for (int i = 0;i < recipesIds.Count(); i++)
8559 {
8560 int key = recipesIds.Get(i);
8561 string recipeName = moduleRecipesManager.GetRecipeName(key);
8562 outputList.Insert(new TSelectableActionInfo(SAT_CRAFTING, key, recipeName));
8563 }
8564 }
8565
8566 // -------------------------------------------------------------------------
8567 override void GetDebugActions(out TSelectableActionInfoArrayEx outputList)
8568 {
8569 super.GetDebugActions(outputList);
8570
8571 //quantity
8572 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_QUANTITY, "Quantity +20%", FadeColors.LIGHT_GREY));
8573 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_QUANTITY, "Quantity -20%", FadeColors.LIGHT_GREY));
8574 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SET_QUANTITY_0, "Set Quantity 0", FadeColors.LIGHT_GREY));
8575 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SET_MAX_QUANTITY, "Set Quantity Max", FadeColors.LIGHT_GREY));
8576 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
8577
8578 //health
8579 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_HEALTH, "Health +20%", FadeColors.LIGHT_GREY));
8580 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_HEALTH, "Health -20%", FadeColors.LIGHT_GREY));
8581 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.DESTROY_HEALTH, "Health 0", FadeColors.LIGHT_GREY));
8582 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
8583 //temperature
8584 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_TEMPERATURE, "Temperature +20", FadeColors.LIGHT_GREY));
8585 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_TEMPERATURE, "Temperature -20", FadeColors.LIGHT_GREY));
8586 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.FLIP_FROZEN, "Toggle Frozen", FadeColors.LIGHT_GREY));
8587 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
8588
8589 //wet
8590 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_WETNESS, "Wetness +20", FadeColors.LIGHT_GREY));
8591 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_WETNESS, "Wetness -20", FadeColors.LIGHT_GREY));
8592 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
8593
8594 //liquidtype
8595 if (IsLiquidContainer())
8596 {
8597 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.LIQUIDTYPE_UP, "LiquidType Next", FadeColors.LIGHT_GREY));
8598 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.LIQUIDTYPE_DOWN, "LiquidType Previous", FadeColors.LIGHT_GREY));
8599 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
8600 }
8601
8602 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.MAKE_SPECIAL, "Make Special", FadeColors.LIGHT_GREY));
8603 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
8604
8605 // watch
8606 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.WATCH_ITEM, "Watch (CTRL-Z)", FadeColors.LIGHT_GREY));
8607 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.WATCH_PLAYER, "Watch Player", FadeColors.LIGHT_GREY));
8608 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
8609
8610 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.DELETE, "Delete", FadeColors.RED));
8611
8612 InventoryLocation loc = new InventoryLocation();
8613 GetInventory().GetCurrentInventoryLocation(loc);
8614 if (!loc || loc.GetType() == InventoryLocationType.GROUND)
8615 {
8616 if (Gizmo_IsSupported())
8617 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.GIZMO_OBJECT, "Gizmo Object", FadeColors.LIGHT_GREY));
8618 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.GIZMO_PHYSICS, "Gizmo Physics (SP Only)", FadeColors.LIGHT_GREY)); // intentionally allowed for testing physics desync
8619 }
8620
8621 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
8622 }
8623
8624 // -------------------------------------------------------------------------
8625 // -------------------------------------------------------------------------
8626 // -------------------------------------------------------------------------
8627 override bool OnAction(int action_id, Man player, ParamsReadContext ctx)
8628 {
8629 super.OnAction(action_id, player, ctx);
8630
8631 if (GetGame().IsClient() || !GetGame().IsMultiplayer())
8632 {
8633 switch (action_id)
8634 {
8635 case EActions.GIZMO_OBJECT:
8636 GetGame().GizmoSelectObject(this);
8637 return true;
8638 case EActions.GIZMO_PHYSICS:
8639 GetGame().GizmoSelectPhysics(GetPhysics());
8640 return true;
8641 }
8642 }
8643
8644 if (GetGame().IsServer())
8645 {
8646 switch (action_id)
8647 {
8648 case EActions.DELETE:
8649 Delete();
8650 return true;
8651 }
8652 }
8653
8654 if (action_id >= EActions.RECIPES_RANGE_START && action_id < EActions.RECIPES_RANGE_END)
8655 {
8656 PluginRecipesManager plugin_recipes_manager = PluginRecipesManager.Cast(GetPlugin(PluginRecipesManager));
8657 int idWithoutOffset = action_id - EActions.RECIPES_RANGE_START;
8658 PlayerBase p = PlayerBase.Cast(player);
8659 if (EActions.RECIPES_RANGE_START < 1000)
8660 {
8661 float anim_length = plugin_recipes_manager.GetRecipeLengthInSecs(idWithoutOffset);
8662 float specialty_weight = plugin_recipes_manager.GetRecipeSpecialty(idWithoutOffset);
8663 }
8664 }
8665 #ifndef SERVER
8666 else if (action_id == EActions.WATCH_PLAYER)
8667 {
8668 PluginDeveloper.SetDeveloperItemClientEx(player);
8669 }
8670 #endif
8671 if (GetGame().IsServer())
8672 {
8673 if (action_id >= EActions.DEBUG_ITEM_WATCH_BUTTON_RANGE_START && action_id < EActions.DEBUG_ITEM_WATCH_BUTTON_RANGE_END)
8674 {
8675 int id = action_id - EActions.DEBUG_ITEM_WATCH_BUTTON_RANGE_START;
8676 OnDebugButtonPressServer(id + 1);
8677 }
8678
8679 else if (action_id >= EActions.DEBUG_AGENTS_RANGE_INJECT_START && action_id < EActions.DEBUG_AGENTS_RANGE_INJECT_END)
8680 {
8681 int agent_id = action_id - EActions.DEBUG_AGENTS_RANGE_INJECT_START;
8682 InsertAgent(agent_id,100);
8683 }
8684
8685 else if (action_id >= EActions.DEBUG_AGENTS_RANGE_REMOVE_START && action_id < EActions.DEBUG_AGENTS_RANGE_REMOVE_END)
8686 {
8687 int agent_id2 = action_id - EActions.DEBUG_AGENTS_RANGE_REMOVE_START;
8688 RemoveAgent(agent_id2);
8689 }
8690
8691 else if (action_id == EActions.ADD_QUANTITY)
8692 {
8693 if (IsMagazine())
8694 {
8695 Magazine mag = Magazine.Cast(this);
8696 mag.ServerSetAmmoCount(mag.GetAmmoCount() + mag.GetAmmoMax() * 0.2);
8697 }
8698 else
8699 {
8700 AddQuantity(GetQuantityMax() * 0.2);
8701 }
8702
8703 if (m_EM)
8704 {
8705 m_EM.AddEnergy(m_EM.GetEnergyMax() * 0.2);
8706 }
8707 //PrintVariables();
8708 }
8709
8710 else if (action_id == EActions.REMOVE_QUANTITY) //Quantity -20%
8711 {
8712 if (IsMagazine())
8713 {
8714 Magazine mag2 = Magazine.Cast(this);
8715 mag2.ServerSetAmmoCount(mag2.GetAmmoCount() - mag2.GetAmmoMax() * 0.2);
8716 }
8717 else
8718 {
8719 AddQuantity(- GetQuantityMax() * 0.2);
8720 }
8721 if (m_EM)
8722 {
8723 m_EM.AddEnergy(- m_EM.GetEnergyMax() * 0.2);
8724 }
8725 //PrintVariables();
8726 }
8727
8728 else if (action_id == EActions.SET_QUANTITY_0) //SetMaxQuantity
8729 {
8730 SetQuantity(0);
8731
8732 if (m_EM)
8733 {
8734 m_EM.SetEnergy(0);
8735 }
8736 }
8737
8738 else if (action_id == EActions.SET_MAX_QUANTITY) //SetMaxQuantity
8739 {
8741
8742 if (m_EM)
8743 {
8744 m_EM.SetEnergy(m_EM.GetEnergyMax());
8745 }
8746 }
8747
8748 else if (action_id == EActions.ADD_HEALTH)
8749 {
8750 AddHealth("","",GetMaxHealth("","Health")/5);
8751 }
8752 else if (action_id == EActions.REMOVE_HEALTH)
8753 {
8754 AddHealth("","",-GetMaxHealth("","Health")/5);
8755 }
8756 else if (action_id == EActions.DESTROY_HEALTH)
8757 {
8758 SetHealth01("","",0);
8759 }
8760 else if (action_id == EActions.WATCH_ITEM)
8761 {
8763 mid.RegisterDebugItem(ItemBase.Cast(this), PlayerBase.Cast(player));
8764 #ifdef DEVELOPER
8765 SetDebugDeveloper_item(this);
8766 #endif
8767 }
8768
8769 else if (action_id == EActions.ADD_TEMPERATURE)
8770 {
8771 AddTemperature(20);
8772 //PrintVariables();
8773 }
8774
8775 else if (action_id == EActions.REMOVE_TEMPERATURE)
8776 {
8777 AddTemperature(-20);
8778 //PrintVariables();
8779 }
8780
8781 else if (action_id == EActions.FLIP_FROZEN)
8782 {
8783 SetFrozen(!GetIsFrozen());
8784 //PrintVariables();
8785 }
8786
8787 else if (action_id == EActions.ADD_WETNESS)
8788 {
8789 AddWet(GetWetMax()/5);
8790 //PrintVariables();
8791 }
8792
8793 else if (action_id == EActions.REMOVE_WETNESS)
8794 {
8795 AddWet(-GetWetMax()/5);
8796 //PrintVariables();
8797 }
8798
8799 else if (action_id == EActions.LIQUIDTYPE_UP)
8800 {
8801 int curr_type = GetLiquidType();
8802 SetLiquidType(curr_type * 2);
8803 //AddWet(1);
8804 //PrintVariables();
8805 }
8806
8807 else if (action_id == EActions.LIQUIDTYPE_DOWN)
8808 {
8809 int curr_type2 = GetLiquidType();
8810 SetLiquidType(curr_type2 / 2);
8811 }
8812
8813 else if (action_id == EActions.MAKE_SPECIAL)
8814 {
8815 auto debugParams = DebugSpawnParams.WithPlayer(player);
8816 OnDebugSpawnEx(debugParams);
8817 }
8818
8819 }
8820
8821
8822 return false;
8823 }
8824
8825 // -------------------------------------------------------------------------
8826
8827
8830 void OnActivatedByTripWire();
8831
8833 void OnActivatedByItem(notnull ItemBase item);
8834
8835 //----------------------------------------------------------------
8836 //returns true if item is able to explode when put in fire
8837 bool CanExplodeInFire()
8838 {
8839 return false;
8840 }
8841
8842 //----------------------------------------------------------------
8843 bool CanEat()
8844 {
8845 return true;
8846 }
8847
8848 //----------------------------------------------------------------
8849 override bool IsIgnoredByConstruction()
8850 {
8851 return true;
8852 }
8853
8854 //----------------------------------------------------------------
8855 //has FoodStages in config?
8856 bool HasFoodStage()
8857 {
8858 string config_path = string.Format("CfgVehicles %1 Food FoodStages", GetType());
8859 return GetGame().ConfigIsExisting(config_path);
8860 }
8861
8863 FoodStage GetFoodStage()
8864 {
8865 return null;
8866 }
8867
8868 bool CanBeCooked()
8869 {
8870 return false;
8871 }
8872
8873 bool CanBeCookedOnStick()
8874 {
8875 return false;
8876 }
8877
8879 void RefreshAudioVisualsOnClient( CookingMethodType cooking_method, bool is_done, bool is_empty, bool is_burned );
8881
8882 //----------------------------------------------------------------
8883 bool CanRepair(ItemBase item_repair_kit)
8884 {
8885 PluginRepairing module_repairing = PluginRepairing.Cast(GetPlugin(PluginRepairing));
8886 return module_repairing.CanRepair(this, item_repair_kit);
8887 }
8888
8889 //----------------------------------------------------------------
8890 bool Repair(PlayerBase player, ItemBase item_repair_kit, float specialty_weight)
8891 {
8892 PluginRepairing module_repairing = PluginRepairing.Cast(GetPlugin(PluginRepairing));
8893 return module_repairing.Repair(player, this, item_repair_kit, specialty_weight);
8894 }
8895
8896 //----------------------------------------------------------------
8897 int GetItemSize()
8898 {
8899 /*
8900 vector v_size = this.ConfigGetVector("itemSize");
8901 int v_size_x = v_size[0];
8902 int v_size_y = v_size[1];
8903 int size = v_size_x * v_size_y;
8904 return size;
8905 */
8906
8907 return 1;
8908 }
8909
8910 //----------------------------------------------------------------
8911 //Override for allowing seemingly unallowed moves when two clients send a conflicting message simultaneously
8912 bool CanBeMovedOverride()
8913 {
8914 return m_CanBeMovedOverride;
8915 }
8916
8917 //----------------------------------------------------------------
8918 //Override for allowing seemingly unallowed moves when two clients send a conflicting message simultaneously
8919 void SetCanBeMovedOverride(bool setting)
8920 {
8921 m_CanBeMovedOverride = setting;
8922 }
8923
8924 //----------------------------------------------------------------
8932 void MessageToOwnerStatus(string text)
8933 {
8934 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
8935
8936 if (player)
8937 {
8938 player.MessageStatus(text);
8939 }
8940 }
8941
8942 //----------------------------------------------------------------
8950 void MessageToOwnerAction(string text)
8951 {
8952 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
8953
8954 if (player)
8955 {
8956 player.MessageAction(text);
8957 }
8958 }
8959
8960 //----------------------------------------------------------------
8968 void MessageToOwnerFriendly(string text)
8969 {
8970 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
8971
8972 if (player)
8973 {
8974 player.MessageFriendly(text);
8975 }
8976 }
8977
8978 //----------------------------------------------------------------
8986 void MessageToOwnerImportant(string text)
8987 {
8988 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
8989
8990 if (player)
8991 {
8992 player.MessageImportant(text);
8993 }
8994 }
8995
8996 override bool IsItemBase()
8997 {
8998 return true;
8999 }
9000
9001 // Checks if item is of questioned kind
9002 override bool KindOf(string tag)
9003 {
9004 bool found = false;
9005 string item_name = this.GetType();
9006 ref TStringArray item_tag_array = new TStringArray;
9007 GetGame().ConfigGetTextArray("cfgVehicles " + item_name + " itemInfo", item_tag_array);
9008
9009 int array_size = item_tag_array.Count();
9010 for (int i = 0; i < array_size; i++)
9011 {
9012 if (item_tag_array.Get(i) == tag)
9013 {
9014 found = true;
9015 break;
9016 }
9017 }
9018 return found;
9019 }
9020
9021
9022 override void OnRPC(PlayerIdentity sender, int rpc_type,ParamsReadContext ctx)
9023 {
9024 //Debug.Log("OnRPC called");
9025 super.OnRPC(sender, rpc_type,ctx);
9026
9027 //Play soundset for attachment locking (ActionLockAttachment.c)
9028 switch (rpc_type)
9029 {
9030 #ifndef SERVER
9031 case ERPCs.RPC_SOUND_LOCK_ATTACH:
9032 Param2<bool, string> p = new Param2<bool, string>(false, "");
9033
9034 if (!ctx.Read(p))
9035 return;
9036
9037 bool play = p.param1;
9038 string soundSet = p.param2;
9039
9040 if (play)
9041 {
9042 if (m_LockingSound)
9043 {
9045 {
9046 m_LockingSound = SEffectManager.PlaySound(soundSet, GetPosition(), 0, 0, true);
9047 }
9048 }
9049 else
9050 {
9051 m_LockingSound = SEffectManager.PlaySound(soundSet, GetPosition(), 0, 0, true);
9052 }
9053 }
9054 else
9055 {
9056 SEffectManager.DestroyEffect(m_LockingSound);
9057 }
9058
9059 break;
9060 #endif
9061
9062 }
9063
9064 if (GetWrittenNoteData())
9065 {
9066 GetWrittenNoteData().OnRPC(sender, rpc_type,ctx);
9067 }
9068 }
9069
9070 //-----------------------------
9071 // VARIABLE MANIPULATION SYSTEM
9072 //-----------------------------
9073 int NameToID(string name)
9074 {
9075 PluginVariables plugin = PluginVariables.Cast(GetPlugin(PluginVariables));
9076 return plugin.GetID(name);
9077 }
9078
9079 string IDToName(int id)
9080 {
9081 PluginVariables plugin = PluginVariables.Cast(GetPlugin(PluginVariables));
9082 return plugin.GetName(id);
9083 }
9084
9086 void OnSyncVariables(ParamsReadContext ctx)//with ID optimization
9087 {
9088 //Debug.Log("OnSyncVariables called for item: "+ ToString(this.GetType()),"varSync");
9089 //read the flags
9090 int varFlags;
9091 if (!ctx.Read(varFlags))
9092 return;
9093
9094 if (varFlags & ItemVariableFlags.FLOAT)
9095 {
9096 ReadVarsFromCTX(ctx);
9097 }
9098 }
9099
9100 override void SerializeNumericalVars(array<float> floats_out)
9101 {
9102 //some variables handled on EntityAI level already!
9103 super.SerializeNumericalVars(floats_out);
9104
9105 // the order of serialization must be the same as the order of de-serialization
9106 //--------------------------------------------
9107 if (IsVariableSet(VARIABLE_QUANTITY))
9108 {
9109 floats_out.Insert(m_VarQuantity);
9110 }
9111 //--------------------------------------------
9112 if (IsVariableSet(VARIABLE_WET))
9113 {
9114 floats_out.Insert(m_VarWet);
9115 }
9116 //--------------------------------------------
9117 if (IsVariableSet(VARIABLE_LIQUIDTYPE))
9118 {
9119 floats_out.Insert(m_VarLiquidType);
9120 }
9121 //--------------------------------------------
9122 if (IsVariableSet(VARIABLE_COLOR))
9123 {
9124 floats_out.Insert(m_ColorComponentR);
9125 floats_out.Insert(m_ColorComponentG);
9126 floats_out.Insert(m_ColorComponentB);
9127 floats_out.Insert(m_ColorComponentA);
9128 }
9129 //--------------------------------------------
9130 if (IsVariableSet(VARIABLE_CLEANNESS))
9131 {
9132 floats_out.Insert(m_Cleanness);
9133 }
9134 }
9135
9136 override void DeSerializeNumericalVars(array<float> floats)
9137 {
9138 //some variables handled on EntityAI level already!
9139 super.DeSerializeNumericalVars(floats);
9140
9141 // the order of serialization must be the same as the order of de-serialization
9142 int index = 0;
9143 int mask = Math.Round(floats.Get(index));
9144
9145 index++;
9146 //--------------------------------------------
9147 if (mask & VARIABLE_QUANTITY)
9148 {
9149 if (m_IsStoreLoad)
9150 {
9151 SetStoreLoadedQuantity(floats.Get(index));
9152 }
9153 else
9154 {
9155 float quantity = floats.Get(index);
9156 SetQuantity(quantity, true, false, false, false);
9157 }
9158 index++;
9159 }
9160 //--------------------------------------------
9161 if (mask & VARIABLE_WET)
9162 {
9163 float wet = floats.Get(index);
9164 SetWet(wet);
9165 index++;
9166 }
9167 //--------------------------------------------
9168 if (mask & VARIABLE_LIQUIDTYPE)
9169 {
9170 int liquidtype = Math.Round(floats.Get(index));
9171 SetLiquidType(liquidtype);
9172 index++;
9173 }
9174 //--------------------------------------------
9175 if (mask & VARIABLE_COLOR)
9176 {
9177 m_ColorComponentR = Math.Round(floats.Get(index));
9178 index++;
9179 m_ColorComponentG = Math.Round(floats.Get(index));
9180 index++;
9181 m_ColorComponentB = Math.Round(floats.Get(index));
9182 index++;
9183 m_ColorComponentA = Math.Round(floats.Get(index));
9184 index++;
9185 }
9186 //--------------------------------------------
9187 if (mask & VARIABLE_CLEANNESS)
9188 {
9189 int cleanness = Math.Round(floats.Get(index));
9190 SetCleanness(cleanness);
9191 index++;
9192 }
9193 }
9194
9195 override void WriteVarsToCTX(ParamsWriteContext ctx)
9196 {
9197 super.WriteVarsToCTX(ctx);
9198
9199 //--------------------------------------------
9200 if (IsVariableSet(VARIABLE_QUANTITY))
9201 {
9202 ctx.Write(GetQuantity());
9203 }
9204 //--------------------------------------------
9205 if (IsVariableSet(VARIABLE_WET))
9206 {
9207 ctx.Write(GetWet());
9208 }
9209 //--------------------------------------------
9210 if (IsVariableSet(VARIABLE_LIQUIDTYPE))
9211 {
9212 ctx.Write(GetLiquidType());
9213 }
9214 //--------------------------------------------
9215 if (IsVariableSet(VARIABLE_COLOR))
9216 {
9217 int r,g,b,a;
9218 GetColor(r,g,b,a);
9219 ctx.Write(r);
9220 ctx.Write(g);
9221 ctx.Write(b);
9222 ctx.Write(a);
9223 }
9224 //--------------------------------------------
9225 if (IsVariableSet(VARIABLE_CLEANNESS))
9226 {
9227 ctx.Write(GetCleanness());
9228 }
9229 }
9230
9231 override bool ReadVarsFromCTX(ParamsReadContext ctx, int version = -1)//with ID optimization
9232 {
9233 if (!super.ReadVarsFromCTX(ctx,version))
9234 return false;
9235
9236 int intValue;
9237 float value;
9238
9239 if (version < 140)
9240 {
9241 if (!ctx.Read(intValue))
9242 return false;
9243
9244 m_VariablesMask = intValue;
9245 }
9246
9247 if (m_VariablesMask & VARIABLE_QUANTITY)
9248 {
9249 if (!ctx.Read(value))
9250 return false;
9251
9252 if (IsStoreLoad())
9253 {
9255 }
9256 else
9257 {
9258 SetQuantity(value, true, false, false, false);
9259 }
9260 }
9261 //--------------------------------------------
9262 if (version < 140)
9263 {
9264 if (m_VariablesMask & VARIABLE_TEMPERATURE)
9265 {
9266 if (!ctx.Read(value))
9267 return false;
9268 SetTemperatureDirect(value);
9269 }
9270 }
9271 //--------------------------------------------
9272 if (m_VariablesMask & VARIABLE_WET)
9273 {
9274 if (!ctx.Read(value))
9275 return false;
9276 SetWet(value);
9277 }
9278 //--------------------------------------------
9279 if (m_VariablesMask & VARIABLE_LIQUIDTYPE)
9280 {
9281 if (!ctx.Read(intValue))
9282 return false;
9283 SetLiquidType(intValue);
9284 }
9285 //--------------------------------------------
9286 if (m_VariablesMask & VARIABLE_COLOR)
9287 {
9288 int r,g,b,a;
9289 if (!ctx.Read(r))
9290 return false;
9291 if (!ctx.Read(g))
9292 return false;
9293 if (!ctx.Read(b))
9294 return false;
9295 if (!ctx.Read(a))
9296 return false;
9297
9298 SetColor(r,g,b,a);
9299 }
9300 //--------------------------------------------
9301 if (m_VariablesMask & VARIABLE_CLEANNESS)
9302 {
9303 if (!ctx.Read(intValue))
9304 return false;
9305 SetCleanness(intValue);
9306 }
9307 //--------------------------------------------
9308 if (version >= 138 && version < 140)
9309 {
9310 if (m_VariablesMask & VARIABLE_TEMPERATURE)
9311 {
9312 if (!ctx.Read(intValue))
9313 return false;
9314 SetFrozen(intValue);
9315 }
9316 }
9317
9318 return true;
9319 }
9320
9321 //----------------------------------------------------------------
9322 override bool OnStoreLoad(ParamsReadContext ctx, int version)
9323 {
9324 m_IsStoreLoad = true;
9326 {
9327 m_FixDamageSystemInit = true;
9328 }
9329
9330 if (!super.OnStoreLoad(ctx, version))
9331 {
9332 m_IsStoreLoad = false;
9333 return false;
9334 }
9335
9336 if (version >= 114)
9337 {
9338 bool hasQuickBarIndexSaved;
9339
9340 if (!ctx.Read(hasQuickBarIndexSaved))
9341 {
9342 m_IsStoreLoad = false;
9343 return false;
9344 }
9345
9346 if (hasQuickBarIndexSaved)
9347 {
9348 int itmQBIndex;
9349
9350 //Load quickbar item bind
9351 if (!ctx.Read(itmQBIndex))
9352 {
9353 m_IsStoreLoad = false;
9354 return false;
9355 }
9356
9357 PlayerBase parentPlayer = PlayerBase.Cast(GetHierarchyRootPlayer());
9358 if (itmQBIndex != -1 && parentPlayer)
9359 parentPlayer.SetLoadedQuickBarItemBind(this, itmQBIndex);
9360 }
9361 }
9362 else
9363 {
9364 // Backup of how it used to be
9365 PlayerBase player;
9366 int itemQBIndex;
9367 if (version == int.MAX)
9368 {
9369 if (!ctx.Read(itemQBIndex))
9370 {
9371 m_IsStoreLoad = false;
9372 return false;
9373 }
9374 }
9375 else if (Class.CastTo(player, GetHierarchyRootPlayer()))
9376 {
9377 //Load quickbar item bind
9378 if (!ctx.Read(itemQBIndex))
9379 {
9380 m_IsStoreLoad = false;
9381 return false;
9382 }
9383 if (itemQBIndex != -1 && player)
9384 player.SetLoadedQuickBarItemBind(this,itemQBIndex);
9385 }
9386 }
9387
9388 if (version < 140)
9389 {
9390 // variable management system
9391 if (!LoadVariables(ctx, version))
9392 {
9393 m_IsStoreLoad = false;
9394 return false;
9395 }
9396 }
9397
9398 //agent trasmission system
9399 if (!LoadAgents(ctx, version))
9400 {
9401 m_IsStoreLoad = false;
9402 return false;
9403 }
9404 if (version >= 132)
9405 {
9406 RemotelyActivatedItemBehaviour raib = GetRemotelyActivatedItemBehaviour();
9407 if (raib)
9408 {
9409 if (!raib.OnStoreLoad(ctx,version))
9410 {
9411 m_IsStoreLoad = false;
9412 return false;
9413 }
9414 }
9415 }
9416
9417 m_IsStoreLoad = false;
9418 return true;
9419 }
9420
9421 //----------------------------------------------------------------
9422
9423 override void OnStoreSave(ParamsWriteContext ctx)
9424 {
9425 super.OnStoreSave(ctx);
9426
9427 PlayerBase player;
9428 if (PlayerBase.CastTo(player,GetHierarchyRootPlayer()))
9429 {
9430 ctx.Write(true); // Keep track of if we should actually read this in or not
9431 //Save quickbar item bind
9432 int itemQBIndex = -1;
9433 itemQBIndex = player.FindQuickBarEntityIndex(this);
9434 ctx.Write(itemQBIndex);
9435 }
9436 else
9437 {
9438 ctx.Write(false); // Keep track of if we should actually read this in or not
9439 }
9440
9441 SaveAgents(ctx);//agent trasmission system
9442
9443 RemotelyActivatedItemBehaviour raib = GetRemotelyActivatedItemBehaviour();
9444 if (raib)
9445 {
9446 raib.OnStoreSave(ctx);
9447 }
9448 }
9449 //----------------------------------------------------------------
9450
9451 override void AfterStoreLoad()
9452 {
9453 super.AfterStoreLoad();
9454
9456 {
9458 }
9459
9460 if (GetStoreLoadedQuantity() != float.LOWEST)
9461 {
9463 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
9464 }
9465 }
9466
9467 override void EEOnAfterLoad()
9468 {
9469 super.EEOnAfterLoad();
9470
9472 {
9473 m_FixDamageSystemInit = false;
9474 }
9475
9478 }
9479
9480 bool CanBeDisinfected()
9481 {
9482 return false;
9483 }
9484
9485
9486 //----------------------------------------------------------------
9487 override void OnVariablesSynchronized()
9488 {
9489 if (m_Initialized)
9490 {
9491 #ifdef PLATFORM_CONSOLE
9492 //bruteforce it is
9493 if (IsSplitable())
9494 {
9495 UIScriptedMenu menu = GetGame().GetUIManager().FindMenu(MENU_INVENTORY);
9496 if (menu)
9497 {
9498 menu.Refresh();
9499 }
9500 }
9501 #endif
9502 }
9503
9505 {
9506 PlayImpactSound(m_ConfigWeight, m_ImpactSpeed, m_ImpactSoundSurfaceHash);
9507 m_WantPlayImpactSound = false;
9508 }
9509
9511 {
9512 SetWeightDirty();
9514 }
9515 if (m_VarWet != m_VarWetPrev)
9516 {
9519 }
9520
9521 if (m_SoundSyncPlay != 0)
9522 {
9523 m_ItemSoundHandler.PlayItemSoundClient(m_SoundSyncPlay);
9524 m_SoundSyncPlay = 0;
9525 }
9526 if (m_SoundSyncStop != 0)
9527 {
9528 m_ItemSoundHandler.StopItemSoundClient(m_SoundSyncStop);
9529 m_SoundSyncStop = 0;
9530 }
9531
9532 super.OnVariablesSynchronized();
9533 }
9534
9535 //------------------------- Quantity
9536 //----------------------------------------------------------------
9538 override bool SetQuantity(float value, bool destroy_config = true, bool destroy_forced = false, bool allow_client = false, bool clamp_to_stack_max = true)
9539 {
9540 if (!IsServerCheck(allow_client))
9541 return false;
9542
9543 if (!HasQuantity())
9544 return false;
9545
9546 float min = GetQuantityMin();
9547 float max = GetQuantityMax();
9548
9549 if (value <= (min + 0.001))
9550 value = min;
9551
9552 if (value == min)
9553 {
9554 if (destroy_config)
9555 {
9556 bool dstr = ConfigGetBool("varQuantityDestroyOnMin");
9557 if (dstr)
9558 {
9559 m_VarQuantity = Math.Clamp(value, min, max);
9560 this.Delete();
9561 return true;
9562 }
9563 }
9564 else if (destroy_forced)
9565 {
9566 m_VarQuantity = Math.Clamp(value, min, max);
9567 this.Delete();
9568 return true;
9569 }
9570 // we get here if destroy_config IS true AND dstr(config destroy param) IS false;
9571 RemoveAllAgents();//we remove all agents when we got to the min value, but the item is not getting deleted
9572 }
9573
9574 float delta = m_VarQuantity;
9575 m_VarQuantity = Math.Clamp(value, min, max);
9576
9577 if (GetStoreLoadedQuantity() == float.LOWEST)//any other value means we are setting quantity from storage
9578 {
9579 delta = m_VarQuantity - delta;
9580
9581 if (delta)
9582 OnQuantityChanged(delta);
9583 }
9584
9585 SetVariableMask(VARIABLE_QUANTITY);
9586
9587 return false;
9588 }
9589
9590 //----------------------------------------------------------------
9592 bool AddQuantity(float value, bool destroy_config = true, bool destroy_forced = false)
9593 {
9594 return SetQuantity(GetQuantity() + value, destroy_config, destroy_forced);
9595 }
9596 //----------------------------------------------------------------
9597 void SetQuantityMax()
9598 {
9599 float max = GetQuantityMax();
9600 SetQuantity(max);
9601 }
9602
9603 override void SetQuantityToMinimum()
9604 {
9605 float min = GetQuantityMin();
9606 SetQuantity(min);
9607 }
9608 //----------------------------------------------------------------
9610 override void SetQuantityNormalized(float value, bool destroy_config = true, bool destroy_forced = false)
9611 {
9612 float value_clamped = Math.Clamp(value, 0, 1);//just to make sure
9613 int result = Math.Round(Math.Lerp(GetQuantityMin(), GetQuantityMax(), value_clamped));
9614 SetQuantity(result, destroy_config, destroy_forced);
9615 }
9616
9617 //----------------------------------------------------------------
9619 override float GetQuantityNormalized()
9620 {
9621 return Math.InverseLerp(GetQuantityMin(), GetQuantityMax(),m_VarQuantity);
9622 }
9623
9625 {
9626 return GetQuantityNormalized();
9627 }
9628
9629 /*void SetAmmoNormalized(float value)
9630 {
9631 float value_clamped = Math.Clamp(value, 0, 1);
9632 Magazine this_mag = Magazine.Cast(this);
9633 int max_rounds = this_mag.GetAmmoMax();
9634 int result = value * max_rounds;//can the rounded if higher precision is required
9635 this_mag.SetAmmoCount(result);
9636 }*/
9637 //----------------------------------------------------------------
9638 override int GetQuantityMax()
9639 {
9640 int slot = -1;
9641 if (GetInventory())
9642 {
9643 InventoryLocation il = new InventoryLocation;
9644 GetInventory().GetCurrentInventoryLocation(il);
9645 slot = il.GetSlot();
9646 }
9647
9648 return GetTargetQuantityMax(slot);
9649 }
9650
9651 override int GetTargetQuantityMax(int attSlotID = -1)
9652 {
9653 float quantity_max = 0;
9654
9655 if (IsSplitable()) //only stackable/splitable items can check for stack size
9656 {
9657 if (attSlotID != -1)
9658 quantity_max = InventorySlots.GetStackMaxForSlotId(attSlotID);
9659
9660 if (quantity_max <= 0)
9661 quantity_max = m_VarStackMax;
9662 }
9663
9664 if (quantity_max <= 0)
9665 quantity_max = m_VarQuantityMax;
9666
9667 return quantity_max;
9668 }
9669 //----------------------------------------------------------------
9670 override int GetQuantityMin()
9671 {
9672 return m_VarQuantityMin;
9673 }
9674 //----------------------------------------------------------------
9675 int GetQuantityInit()
9676 {
9677 return m_VarQuantityInit;
9678 }
9679
9680 //----------------------------------------------------------------
9681 override bool HasQuantity()
9682 {
9683 return !(GetQuantityMax() - GetQuantityMin() == 0);
9684 }
9685
9686 override float GetQuantity()
9687 {
9688 return m_VarQuantity;
9689 }
9690
9691 bool IsFullQuantity()
9692 {
9693 return GetQuantity() >= GetQuantityMax();
9694 }
9695
9696 //Calculates weight of single item without attachments and cargo
9697 override float GetSingleInventoryItemWeightEx()
9698 {
9699 //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
9700 float weightEx = GetWeightEx();//overall weight of the item
9701 float special = GetInventoryAndCargoWeight();//cargo and attachment weight
9702 return weightEx - special;
9703 }
9704
9705 // Obsolete, use GetSingleInventoryItemWeightEx() instead
9707 {
9709 }
9710
9711 override protected float GetWeightSpecialized(bool forceRecalc = false)
9712 {
9713 if (IsSplitable()) //quantity determines size of the stack
9714 {
9715 #ifdef DEVELOPER
9716 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
9717 {
9718 WeightDebugData data1 = WeightDebug.GetWeightDebug(this);
9719 data1.SetCalcDetails("TIB1: " + GetConfigWeightModifiedDebugText() +" * " + GetQuantity()+"(quantity)");
9720 }
9721 #endif
9722
9723 return GetQuantity() * GetConfigWeightModified();
9724 }
9725 else if (HasEnergyManager())// items with energy manager
9726 {
9727 #ifdef DEVELOPER
9728 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
9729 {
9730 WeightDebugData data2 = WeightDebug.GetWeightDebug(this);
9731 data2.SetCalcDetails("TIB2: "+super.GetWeightSpecialized(forceRecalc)+"(contents weight) + " + GetConfigWeightModifiedDebugText() +" + " + GetCompEM().GetEnergy()+"(energy) * " + ConfigGetFloat("weightPerQuantityUnit") +"(weightPerQuantityUnit)");
9732 }
9733 #endif
9734 return super.GetWeightSpecialized(forceRecalc) + (GetCompEM().GetEnergy() * ConfigGetFloat("weightPerQuantityUnit")) + GetConfigWeightModified();
9735 }
9736 else//everything else
9737 {
9738 #ifdef DEVELOPER
9739 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
9740 {
9741 WeightDebugData data3 = WeightDebug.GetWeightDebug(this);
9742 data3.SetCalcDetails("TIB3: "+super.GetWeightSpecialized(forceRecalc)+"(contents weight) + " + GetConfigWeightModifiedDebugText() +" + " + GetQuantity()+"(quantity) * " + ConfigGetFloat("weightPerQuantityUnit") +"(weightPerQuantityUnit))");
9743 }
9744 #endif
9745 return super.GetWeightSpecialized(forceRecalc) + (GetQuantity() * ConfigGetFloat("weightPerQuantityUnit")) + GetConfigWeightModified();
9746 }
9747 }
9748
9750 int GetNumberOfItems()
9751 {
9752 int item_count = 0;
9753 ItemBase item;
9754
9755 if (GetInventory().GetCargo() != NULL)
9756 {
9757 item_count = GetInventory().GetCargo().GetItemCount();
9758 }
9759
9760 for (int i = 0; i < GetInventory().AttachmentCount(); i++)
9761 {
9762 Class.CastTo(item,GetInventory().GetAttachmentFromIndex(i));
9763 if (item)
9764 item_count += item.GetNumberOfItems();
9765 }
9766 return item_count;
9767 }
9768
9770 float GetUnitWeight(bool include_wetness = true)
9771 {
9772 float weight = 0;
9773 float wetness = 1;
9774 if (include_wetness)
9775 wetness += GetWet();
9776 if (IsSplitable()) //quantity determines size of the stack
9777 {
9778 weight = wetness * m_ConfigWeight;
9779 }
9780 else if (IsLiquidContainer()) //is a liquid container, default liquid weight is set to 1. May revisit later?
9781 {
9782 weight = 1;
9783 }
9784 return weight;
9785 }
9786
9787 //-----------------------------------------------------------------
9788
9789 override void ClearInventory()
9790 {
9791 if ((GetGame().IsServer() || !GetGame().IsMultiplayer()) && GetInventory())
9792 {
9793 GameInventory inv = GetInventory();
9794 array<EntityAI> items = new array<EntityAI>;
9795 inv.EnumerateInventory(InventoryTraversalType.INORDER, items);
9796 for (int i = 0; i < items.Count(); i++)
9797 {
9798 ItemBase item = ItemBase.Cast(items.Get(i));
9799 if (item)
9800 {
9801 GetGame().ObjectDelete(item);
9802 }
9803 }
9804 }
9805 }
9806
9807 //------------------------- Energy
9808
9809 //----------------------------------------------------------------
9810 float GetEnergy()
9811 {
9812 float energy = 0;
9813 if (HasEnergyManager())
9814 {
9815 energy = GetCompEM().GetEnergy();
9816 }
9817 return energy;
9818 }
9819
9820
9821 override void OnEnergyConsumed()
9822 {
9823 super.OnEnergyConsumed();
9824
9826 }
9827
9828 override void OnEnergyAdded()
9829 {
9830 super.OnEnergyAdded();
9831
9833 }
9834
9835 // Converts energy (from Energy Manager) to quantity, if enabled.
9837 {
9838 if (GetGame().IsServer() && HasEnergyManager() && GetCompEM().HasConversionOfEnergyToQuantity())
9839 {
9840 if (HasQuantity())
9841 {
9842 float energy_0to1 = GetCompEM().GetEnergy0To1();
9843 SetQuantityNormalized(energy_0to1);
9844 }
9845 }
9846 }
9847
9848 //----------------------------------------------------------------
9849 float GetHeatIsolationInit()
9850 {
9851 return ConfigGetFloat("heatIsolation");
9852 }
9853
9854 float GetHeatIsolation()
9855 {
9856 return m_HeatIsolation;
9857 }
9858
9859 float GetDryingIncrement(string pIncrementName)
9860 {
9861 string paramPath = string.Format("CfgVehicles %1 EnvironmentWetnessIncrements Drying %2", GetType(), pIncrementName);
9862 if (GetGame().ConfigIsExisting(paramPath))
9863 return GetGame().ConfigGetFloat(paramPath);
9864
9865 return 0.0;
9866 }
9867
9868 float GetSoakingIncrement(string pIncrementName)
9869 {
9870 string paramPath = string.Format("CfgVehicles %1 EnvironmentWetnessIncrements Soaking %2", GetType(), pIncrementName);
9871 if (GetGame().ConfigIsExisting(paramPath))
9872 return GetGame().ConfigGetFloat(paramPath);
9873
9874 return 0.0;
9875 }
9876 //----------------------------------------------------------------
9877 override void SetWet(float value, bool allow_client = false)
9878 {
9879 if (!IsServerCheck(allow_client))
9880 return;
9881
9882 float min = GetWetMin();
9883 float max = GetWetMax();
9884
9885 float previousValue = m_VarWet;
9886
9887 m_VarWet = Math.Clamp(value, min, max);
9888
9889 if (previousValue != m_VarWet)
9890 {
9891 SetVariableMask(VARIABLE_WET);
9892 OnWetChanged(m_VarWet, previousValue);
9893 }
9894 }
9895 //----------------------------------------------------------------
9896 override void AddWet(float value)
9897 {
9898 SetWet(GetWet() + value);
9899 }
9900 //----------------------------------------------------------------
9901 override void SetWetMax()
9902 {
9904 }
9905 //----------------------------------------------------------------
9906 override float GetWet()
9907 {
9908 return m_VarWet;
9909 }
9910 //----------------------------------------------------------------
9911 override float GetWetMax()
9912 {
9913 return m_VarWetMax;
9914 }
9915 //----------------------------------------------------------------
9916 override float GetWetMin()
9917 {
9918 return m_VarWetMin;
9919 }
9920 //----------------------------------------------------------------
9921 override float GetWetInit()
9922 {
9923 return m_VarWetInit;
9924 }
9925 //----------------------------------------------------------------
9926 override void OnWetChanged(float newVal, float oldVal)
9927 {
9928 EWetnessLevel newLevel = GetWetLevelInternal(newVal);
9929 EWetnessLevel oldLevel = GetWetLevelInternal(oldVal);
9930 if (newLevel != oldLevel)
9931 {
9932 OnWetLevelChanged(newLevel,oldLevel);
9933 }
9934 }
9935
9936 override void OnWetLevelChanged(EWetnessLevel newLevel, EWetnessLevel oldLevel)
9937 {
9938 SetWeightDirty();
9939 }
9940
9941 override EWetnessLevel GetWetLevel()
9942 {
9943 return GetWetLevelInternal(m_VarWet);
9944 }
9945
9946 //----------------------------------------------------------------
9947
9948 override void SetStoreLoad(bool value)
9949 {
9950 m_IsStoreLoad = value;
9951 }
9952
9953 override bool IsStoreLoad()
9954 {
9955 return m_IsStoreLoad;
9956 }
9957
9958 override void SetStoreLoadedQuantity(float value)
9959 {
9960 m_StoreLoadedQuantity = value;
9961 }
9962
9963 override float GetStoreLoadedQuantity()
9964 {
9965 return m_StoreLoadedQuantity;
9966 }
9967
9968 //----------------------------------------------------------------
9969
9970 float GetItemModelLength()
9971 {
9972 if (ConfigIsExisting("itemModelLength"))
9973 {
9974 return ConfigGetFloat("itemModelLength");
9975 }
9976 return 0;
9977 }
9978
9979 float GetItemAttachOffset()
9980 {
9981 if (ConfigIsExisting("itemAttachOffset"))
9982 {
9983 return ConfigGetFloat("itemAttachOffset");
9984 }
9985 return 0;
9986 }
9987
9988 override void SetCleanness(int value, bool allow_client = false)
9989 {
9990 if (!IsServerCheck(allow_client))
9991 return;
9992
9993 int previousValue = m_Cleanness;
9994
9995 m_Cleanness = Math.Clamp(value, m_CleannessMin, m_CleannessMax);
9996
9997 if (previousValue != m_Cleanness)
9998 SetVariableMask(VARIABLE_CLEANNESS);
9999 }
10000
10001 override int GetCleanness()
10002 {
10003 return m_Cleanness;
10004 }
10005
10007 {
10008 return true;
10009 }
10010
10011 //----------------------------------------------------------------
10012 // ATTACHMENT LOCKING
10013 // Getters relevant to generic ActionLockAttachment
10014 int GetLockType()
10015 {
10016 return m_LockType;
10017 }
10018
10019 string GetLockSoundSet()
10020 {
10021 return m_LockSoundSet;
10022 }
10023
10024 //----------------------------------------------------------------
10025 //------------------------- Color
10026 // sets items color variable given color components
10027 override void SetColor(int r, int g, int b, int a)
10028 {
10033 SetVariableMask(VARIABLE_COLOR);
10034 }
10036 override void GetColor(out int r,out int g,out int b,out int a)
10037 {
10042 }
10043
10044 bool IsColorSet()
10045 {
10046 return IsVariableSet(VARIABLE_COLOR);
10047 }
10048
10050 string GetColorString()
10051 {
10052 int r,g,b,a;
10053 GetColor(r,g,b,a);
10054 r = r/255;
10055 g = g/255;
10056 b = b/255;
10057 a = a/255;
10058 return MiscGameplayFunctions.GetColorString(r, g, b, a);
10059 }
10060 //----------------------------------------------------------------
10061 //------------------------- LiquidType
10062
10063 override void SetLiquidType(int value, bool allow_client = false)
10064 {
10065 if (!IsServerCheck(allow_client))
10066 return;
10067
10068 int old = m_VarLiquidType;
10069 m_VarLiquidType = value;
10070 OnLiquidTypeChanged(old,value);
10071 SetVariableMask(VARIABLE_LIQUIDTYPE);
10072 }
10073
10074 int GetLiquidTypeInit()
10075 {
10076 return ConfigGetInt("varLiquidTypeInit");
10077 }
10078
10079 override int GetLiquidType()
10080 {
10081 return m_VarLiquidType;
10082 }
10083
10084 protected void OnLiquidTypeChanged(int oldType, int newType)
10085 {
10086 if (newType == LIQUID_NONE && GetIsFrozen())
10087 SetFrozen(false);
10088 }
10089
10091 void UpdateQuickbarShortcutVisibility(PlayerBase player)
10092 {
10093 player.SetEnableQuickBarEntityShortcut(this,!GetHierarchyParent() || GetHierarchyParent().GetInventory().AreChildrenAccessible());
10094 }
10095
10096 // -------------------------------------------------------------------------
10098 void OnInventoryEnter(Man player)
10099 {
10100 PlayerBase nplayer;
10101 if (PlayerBase.CastTo(nplayer, player))
10102 {
10103 m_CanPlayImpactSound = true;
10104 //nplayer.OnItemInventoryEnter(this);
10105 nplayer.SetEnableQuickBarEntityShortcut(this,!GetHierarchyParent() || GetHierarchyParent().GetInventory().AreChildrenAccessible());
10106 }
10107 }
10108
10109 // -------------------------------------------------------------------------
10111 void OnInventoryExit(Man player)
10112 {
10113 PlayerBase nplayer;
10114 if (PlayerBase.CastTo(nplayer,player))
10115 {
10116 //nplayer.OnItemInventoryExit(this);
10117 nplayer.SetEnableQuickBarEntityShortcut(this,false);
10118
10119 }
10120
10121 //if (!GetGame().IsDedicatedServer())
10122 player.GetHumanInventory().ClearUserReservedLocationForContainer(this);
10123
10124
10125 if (HasEnergyManager())
10126 {
10127 GetCompEM().UpdatePlugState(); // Unplug the el. device if it's necesarry.
10128 }
10129 }
10130
10131 // ADVANCED PLACEMENT EVENTS
10132 override void OnPlacementStarted(Man player)
10133 {
10134 super.OnPlacementStarted(player);
10135
10136 SetTakeable(false);
10137 }
10138
10139 override void OnPlacementComplete(Man player, vector position = "0 0 0", vector orientation = "0 0 0")
10140 {
10141 if (m_AdminLog)
10142 {
10143 m_AdminLog.OnPlacementComplete(player, this);
10144 }
10145
10146 super.OnPlacementComplete(player, position, orientation);
10147 }
10148
10149 //-----------------------------
10150 // AGENT SYSTEM
10151 //-----------------------------
10152 //--------------------------------------------------------------------------
10153 bool ContainsAgent(int agent_id)
10154 {
10155 if (agent_id & m_AttachedAgents)
10156 {
10157 return true;
10158 }
10159 else
10160 {
10161 return false;
10162 }
10163 }
10164
10165 //--------------------------------------------------------------------------
10166 override void RemoveAgent(int agent_id)
10167 {
10168 if (ContainsAgent(agent_id))
10169 {
10170 m_AttachedAgents = ~agent_id & m_AttachedAgents;
10171 }
10172 }
10173
10174 //--------------------------------------------------------------------------
10175 override void RemoveAllAgents()
10176 {
10177 m_AttachedAgents = 0;
10178 }
10179 //--------------------------------------------------------------------------
10180 override void RemoveAllAgentsExcept(int agent_to_keep)
10181 {
10182 m_AttachedAgents = m_AttachedAgents & agent_to_keep;
10183 }
10184 // -------------------------------------------------------------------------
10185 override void InsertAgent(int agent, float count = 1)
10186 {
10187 if (count < 1)
10188 return;
10189 //Debug.Log("Inserting Agent on item: " + agent.ToString() +" count: " + count.ToString());
10191 }
10192
10194 void TransferAgents(int agents)
10195 {
10197 }
10198
10199 // -------------------------------------------------------------------------
10200 override int GetAgents()
10201 {
10202 return m_AttachedAgents;
10203 }
10204 //----------------------------------------------------------------------
10205
10206 /*int GetContaminationType()
10207 {
10208 int contamination_type;
10209
10210 const int CONTAMINATED_MASK = eAgents.CHOLERA | eAgents.INFLUENZA | eAgents.SALMONELLA | eAgents.BRAIN;
10211 const int POISONED_MASK = eAgents.FOOD_POISON | eAgents.CHEMICAL_POISON;
10212 const int NERVE_GAS_MASK = eAgents.CHEMICAL_POISON;
10213 const int DIRTY_MASK = eAgents.WOUND_AGENT;
10214
10215 Edible_Base edible = Edible_Base.Cast(this);
10216 int agents = GetAgents();
10217 if (edible)
10218 {
10219 NutritionalProfile profile = Edible_Base.GetNutritionalProfile(edible);
10220 if (profile)
10221 {
10222 agents = agents | profile.GetAgents();//merge item's agents with nutritional agents
10223 }
10224 }
10225 if (agents & CONTAMINATED_MASK)
10226 {
10227 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_CONTAMINATED;
10228 }
10229 if (agents & POISONED_MASK)
10230 {
10231 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_POISONED;
10232 }
10233 if (agents & NERVE_GAS_MASK)
10234 {
10235 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_NERVE_GAS;
10236 }
10237 if (agents & DIRTY_MASK)
10238 {
10239 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_DIRTY;
10240 }
10241
10242 return agents;
10243 }*/
10244
10245 // -------------------------------------------------------------------------
10246 bool LoadAgents(ParamsReadContext ctx, int version)
10247 {
10248 if (!ctx.Read(m_AttachedAgents))
10249 return false;
10250 return true;
10251 }
10252 // -------------------------------------------------------------------------
10254 {
10255
10257 }
10258 // -------------------------------------------------------------------------
10259
10261 override void CheckForRoofLimited(float timeTresholdMS = 3000)
10262 {
10263 super.CheckForRoofLimited(timeTresholdMS);
10264
10265 float time = GetGame().GetTime();
10266 if ((time - m_PreviousRoofTestTime) >= timeTresholdMS)
10267 {
10268 m_PreviousRoofTestTime = time;
10269 SetRoofAbove(MiscGameplayFunctions.IsUnderRoof(this));
10270 }
10271 }
10272
10273 // returns item's protection level against enviromental hazard, for masks with filters, returns the filters protection for valid filter, otherwise 0
10274 float GetProtectionLevel(int type, bool consider_filter = false, int system = 0)
10275 {
10276 if (IsDamageDestroyed() || (HasQuantity() && GetQuantity() <= 0))
10277 {
10278 return 0;
10279 }
10280
10281 if (GetInventory().GetAttachmentSlotsCount() != 0)//is it an item with attachable filter ?
10282 {
10283 ItemBase filter = ItemBase.Cast(FindAttachmentBySlotName("GasMaskFilter"));
10284 if (filter)
10285 return filter.GetProtectionLevel(type, false, system);//it's a valid filter, return the protection
10286 else
10287 return 0;//otherwise return 0 when no filter attached
10288 }
10289
10290 string subclassPath, entryName;
10291
10292 switch (type)
10293 {
10294 case DEF_BIOLOGICAL:
10295 entryName = "biological";
10296 break;
10297 case DEF_CHEMICAL:
10298 entryName = "chemical";
10299 break;
10300 default:
10301 entryName = "biological";
10302 break;
10303 }
10304
10305 subclassPath = "CfgVehicles " + this.GetType() + " Protection ";
10306
10307 return GetGame().ConfigGetFloat(subclassPath + entryName);
10308 }
10309
10310
10311
10313 override void EEOnCECreate()
10314 {
10315 if (!IsMagazine())
10317
10319 }
10320
10321
10322 //-------------------------
10323 // OPEN/CLOSE USER ACTIONS
10324 //-------------------------
10326 void Open();
10327 void Close();
10328 bool IsOpen()
10329 {
10330 return true;
10331 }
10332
10333 override bool CanDisplayCargo()
10334 {
10335 return IsOpen();
10336 }
10337
10338
10339 // ------------------------------------------------------------
10340 // CONDITIONS
10341 // ------------------------------------------------------------
10342 override bool CanPutInCargo(EntityAI parent)
10343 {
10344 if (parent)
10345 {
10346 if (parent.IsInherited(DayZInfected))
10347 return true;
10348
10349 if (!parent.IsRuined())
10350 return true;
10351 }
10352
10353 return true;
10354 }
10355
10356 override bool CanPutAsAttachment(EntityAI parent)
10357 {
10358 if (!super.CanPutAsAttachment(parent))
10359 {
10360 return false;
10361 }
10362
10363 if (!IsRuined() && !parent.IsRuined())
10364 {
10365 return true;
10366 }
10367
10368 return false;
10369 }
10370
10371 override bool CanReceiveItemIntoCargo(EntityAI item)
10372 {
10373 //removed 15.06. coz of loading from storage -> after load items in cargo was lost -> waiting for proper solution
10374 //if (GetHealthLevel() == GameConstants.STATE_RUINED)
10375 // return false;
10376
10377 return super.CanReceiveItemIntoCargo(item);
10378 }
10379
10380 override bool CanReceiveAttachment(EntityAI attachment, int slotId)
10381 {
10382 //removed 15.06. coz of loading from storage -> after load items in cargo was lost -> waiting for proper solution
10383 //if (GetHealthLevel() == GameConstants.STATE_RUINED)
10384 // return false;
10385
10386 GameInventory attachmentInv = attachment.GetInventory();
10387 if (attachmentInv && attachmentInv.GetCargo() && attachmentInv.GetCargo().GetItemCount() > 0)
10388 {
10389 if (GetHierarchyParent() && !GetHierarchyParent().IsInherited(PlayerBase))
10390 return false;
10391 }
10392
10393 InventoryLocation loc = new InventoryLocation();
10394 attachment.GetInventory().GetCurrentInventoryLocation(loc);
10395 if (loc && loc.IsValid() && !GetInventory().AreChildrenAccessible())
10396 return false;
10397
10398 return super.CanReceiveAttachment(attachment, slotId);
10399 }
10400
10401 override bool CanReleaseAttachment(EntityAI attachment)
10402 {
10403 if (!super.CanReleaseAttachment(attachment))
10404 return false;
10405
10406 return GetInventory().AreChildrenAccessible();
10407 }
10408
10409 /*override bool CanLoadAttachment(EntityAI attachment)
10410 {
10411 //removed 15.06. coz of loading from storage -> after load items in cargo was lost -> waiting for proper solution
10412 //if (GetHealthLevel() == GameConstants.STATE_RUINED)
10413 // return false;
10414
10415 GameInventory attachmentInv = attachment.GetInventory();
10416 if (attachmentInv && attachmentInv.GetCargo() && attachmentInv.GetCargo().GetItemCount() > 0)
10417 {
10418 bool boo = (GetHierarchyParent() && !GetHierarchyParent().IsInherited(PlayerBase));
10419 ErrorEx("CanLoadAttachment | this: " + this + " | attachment: " + attachment + " | boo: " + boo,ErrorExSeverity.INFO);
10420
10421 if (GetHierarchyParent() && !GetHierarchyParent().IsInherited(PlayerBase))
10422 return false;
10423 }
10424
10425 return super.CanLoadAttachment(attachment);
10426 }*/
10427
10428 // Plays muzzle flash particle effects
10429 static void PlayFireParticles(ItemBase weapon, int muzzle_index, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
10430 {
10431 int id = muzzle_owner.GetMuzzleID();
10432 array<ref WeaponParticlesOnFire> WPOF_array = m_OnFireEffect.Get(id);
10433
10434 if (WPOF_array)
10435 {
10436 for (int i = 0; i < WPOF_array.Count(); i++)
10437 {
10438 WeaponParticlesOnFire WPOF = WPOF_array.Get(i);
10439
10440 if (WPOF)
10441 {
10442 WPOF.OnActivate(weapon, muzzle_index, ammoType, muzzle_owner, suppressor, config_to_search);
10443 }
10444 }
10445 }
10446 }
10447
10448 // Plays bullet eject particle effects (usually just smoke, the bullet itself is a 3D model and is not part of this function)
10449 static void PlayBulletCasingEjectParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
10450 {
10451 int id = muzzle_owner.GetMuzzleID();
10452 array<ref WeaponParticlesOnBulletCasingEject> WPOBE_array = m_OnBulletCasingEjectEffect.Get(id);
10453
10454 if (WPOBE_array)
10455 {
10456 for (int i = 0; i < WPOBE_array.Count(); i++)
10457 {
10458 WeaponParticlesOnBulletCasingEject WPOBE = WPOBE_array.Get(i);
10459
10460 if (WPOBE)
10461 {
10462 WPOBE.OnActivate(weapon, 0, ammoType, muzzle_owner, suppressor, config_to_search);
10463 }
10464 }
10465 }
10466 }
10467
10468 // Plays all weapon overheating particles
10469 static void PlayOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
10470 {
10471 int id = muzzle_owner.GetMuzzleID();
10472 array<ref WeaponParticlesOnOverheating> WPOOH_array = weapon.m_OnOverheatingEffect.Get(id);
10473
10474 if (WPOOH_array)
10475 {
10476 for (int i = 0; i < WPOOH_array.Count(); i++)
10477 {
10478 WeaponParticlesOnOverheating WPOOH = WPOOH_array.Get(i);
10479
10480 if (WPOOH)
10481 {
10482 WPOOH.OnActivate(weapon, 0, ammoType, muzzle_owner, suppressor, config_to_search);
10483 }
10484 }
10485 }
10486 }
10487
10488 // Updates all weapon overheating particles
10489 static void UpdateOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
10490 {
10491 int id = muzzle_owner.GetMuzzleID();
10492 array<ref WeaponParticlesOnOverheating> WPOOH_array = weapon.m_OnOverheatingEffect.Get(id);
10493
10494 if (WPOOH_array)
10495 {
10496 for (int i = 0; i < WPOOH_array.Count(); i++)
10497 {
10498 WeaponParticlesOnOverheating WPOOH = WPOOH_array.Get(i);
10499
10500 if (WPOOH)
10501 {
10502 WPOOH.OnUpdate(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
10503 }
10504 }
10505 }
10506 }
10507
10508 // Stops overheating particles
10509 static void StopOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
10510 {
10511 int id = muzzle_owner.GetMuzzleID();
10512 array<ref WeaponParticlesOnOverheating> WPOOH_array = weapon.m_OnOverheatingEffect.Get(id);
10513
10514 if (WPOOH_array)
10515 {
10516 for (int i = 0; i < WPOOH_array.Count(); i++)
10517 {
10518 WeaponParticlesOnOverheating WPOOH = WPOOH_array.Get(i);
10519
10520 if (WPOOH)
10521 {
10522 WPOOH.OnDeactivate(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
10523 }
10524 }
10525 }
10526 }
10527
10528 //----------------------------------------------------------------
10529 //Item Behaviour - unified approach
10530 override bool IsHeavyBehaviour()
10531 {
10532 if (m_ItemBehaviour == 0)
10533 {
10534 return true;
10535 }
10536
10537 return false;
10538 }
10539
10540 override bool IsOneHandedBehaviour()
10541 {
10542 if (m_ItemBehaviour == 1)
10543 {
10544 return true;
10545 }
10546
10547 return false;
10548 }
10549
10550 override bool IsTwoHandedBehaviour()
10551 {
10552 if (m_ItemBehaviour == 2)
10553 {
10554 return true;
10555 }
10556
10557 return false;
10558 }
10559
10560 bool IsDeployable()
10561 {
10562 return false;
10563 }
10564
10566 float GetDeployTime()
10567 {
10568 return UATimeSpent.DEFAULT_DEPLOY;
10569 }
10570
10571
10572 //----------------------------------------------------------------
10573 // Item Targeting (User Actions)
10574 override void SetTakeable(bool pState)
10575 {
10576 m_IsTakeable = pState;
10577 SetSynchDirty();
10578 }
10579
10580 override bool IsTakeable()
10581 {
10582 return m_IsTakeable;
10583 }
10584
10585 // For cases where we want to show object widget which cant be taken to hands
10587 {
10588 return false;
10589 }
10590
10592 protected void PreLoadSoundAttachmentType()
10593 {
10594 string att_type = "None";
10595
10596 if (ConfigIsExisting("soundAttType"))
10597 {
10598 att_type = ConfigGetString("soundAttType");
10599 }
10600
10601 m_SoundAttType = att_type;
10602 }
10603
10604 override string GetAttachmentSoundType()
10605 {
10606 return m_SoundAttType;
10607 }
10608
10609 //----------------------------------------------------------------
10610 //SOUNDS - ItemSoundHandler
10611 //----------------------------------------------------------------
10612
10613 string GetPlaceSoundset(); // played when deploy starts
10614 string GetLoopDeploySoundset(); // played when deploy starts and stopped when it finishes
10615 string GetDeploySoundset(); // played when deploy sucessfully finishes
10616 string GetLoopFoldSoundset(); // played when fold starts and stopped when it finishes
10617 string GetFoldSoundset(); // played when fold sucessfully finishes
10618
10620 {
10621 if (!m_ItemSoundHandler)
10623
10624 return m_ItemSoundHandler;
10625 }
10626
10627 // override to initialize sounds
10628 protected void InitItemSounds()
10629 {
10630 if (GetPlaceSoundset() == string.Empty && GetDeploySoundset() == string.Empty && GetLoopDeploySoundset() == string.Empty)
10631 return;
10632
10634
10635 if (GetPlaceSoundset() != string.Empty)
10636 handler.AddSound(SoundConstants.ITEM_PLACE, GetPlaceSoundset());
10637
10638 if (GetDeploySoundset() != string.Empty)
10639 handler.AddSound(SoundConstants.ITEM_DEPLOY, GetDeploySoundset());
10640
10641 SoundParameters params = new SoundParameters();
10642 params.m_Loop = true;
10643 if (GetLoopDeploySoundset() != string.Empty)
10644 handler.AddSound(SoundConstants.ITEM_DEPLOY_LOOP, GetLoopDeploySoundset(), params);
10645 }
10646
10647 // Start sound using ItemSoundHandler
10648 void StartItemSoundServer(int id)
10649 {
10650 if (!GetGame().IsServer())
10651 return;
10652
10653 m_SoundSyncPlay = id;
10654 SetSynchDirty();
10655
10656 GetGame().GetCallQueue(CALL_CATEGORY_SYSTEM).Remove(ClearStartItemSoundServer); // in case one is queued already
10658 }
10659
10660 // Stop sound using ItemSoundHandler
10661 void StopItemSoundServer(int id)
10662 {
10663 if (!GetGame().IsServer())
10664 return;
10665
10666 m_SoundSyncStop = id;
10667 SetSynchDirty();
10668
10669 GetGame().GetCallQueue(CALL_CATEGORY_SYSTEM).Remove(ClearStopItemSoundServer); // in case one is queued already
10671 }
10672
10673 protected void ClearStartItemSoundServer()
10674 {
10675 m_SoundSyncPlay = 0;
10676 }
10677
10678 protected void ClearStopItemSoundServer()
10679 {
10680 m_SoundSyncStop = 0;
10681 }
10682
10684 void PlayAttachSound(string slot_type)
10685 {
10686 if (!GetGame().IsDedicatedServer())
10687 {
10688 if (ConfigIsExisting("attachSoundSet"))
10689 {
10690 string cfg_path = "";
10691 string soundset = "";
10692 string type_name = GetType();
10693
10694 TStringArray cfg_soundset_array = new TStringArray;
10695 TStringArray cfg_slot_array = new TStringArray;
10696 ConfigGetTextArray("attachSoundSet",cfg_soundset_array);
10697 ConfigGetTextArray("attachSoundSlot",cfg_slot_array);
10698
10699 if (cfg_soundset_array.Count() > 0 && cfg_soundset_array.Count() == cfg_slot_array.Count())
10700 {
10701 for (int i = 0; i < cfg_soundset_array.Count(); i++)
10702 {
10703 if (cfg_slot_array[i] == slot_type)
10704 {
10705 soundset = cfg_soundset_array[i];
10706 break;
10707 }
10708 }
10709 }
10710
10711 if (soundset != "")
10712 {
10713 EffectSound sound = SEffectManager.PlaySound(soundset, GetPosition());
10714 sound.SetAutodestroy(true);
10715 }
10716 }
10717 }
10718 }
10719
10720 void PlayDetachSound(string slot_type)
10721 {
10722 //TODO - evaluate if needed and devise universal config structure if so
10723 }
10724
10725 void OnApply(PlayerBase player);
10726
10728 {
10729 return 1.0;
10730 };
10731 //returns applicable selection
10732 array<string> GetHeadHidingSelection()
10733 {
10735 }
10736
10738 {
10740 }
10741
10742 WrittenNoteData GetWrittenNoteData() {};
10743
10745 {
10746 SetDynamicPhysicsLifeTime(0.01);
10747 m_ItemBeingDroppedPhys = false;
10748 }
10749
10751 {
10752 array<string> zone_names = new array<string>;
10753 GetDamageZones(zone_names);
10754 for (int i = 0; i < zone_names.Count(); i++)
10755 {
10756 SetHealthMax(zone_names.Get(i),"Health");
10757 }
10758 SetHealthMax("","Health");
10759 }
10760
10762 void SetZoneDamageCEInit()
10763 {
10764 float global_health = GetHealth01("","Health");
10765 array<string> zones = new array<string>;
10766 GetDamageZones(zones);
10767 //set damage of all zones to match global health level
10768 for (int i = 0; i < zones.Count(); i++)
10769 {
10770 SetHealth01(zones.Get(i),"Health",global_health);
10771 }
10772 }
10773
10775 bool IsCoverFaceForShave(string slot_name)
10776 {
10777 return IsExclusionFlagPresent(PlayerBase.GetFaceCoverageShaveValues());
10778 }
10779
10780 void ProcessItemWetness(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
10781 {
10782 if (!hasRootAsPlayer)
10783 {
10784 if (refParentIB)
10785 {
10786 // parent is wet
10787 if ((refParentIB.GetWet() >= GameConstants.STATE_SOAKING_WET) && (m_VarWet < m_VarWetMax))
10788 AddWet(delta * GameConstants.WETNESS_RATE_WETTING_INSIDE);
10789 // parent has liquid inside
10790 else if ((refParentIB.GetLiquidType() != 0) && (refParentIB.GetQuantity() > 0) && (m_VarWet < m_VarWetMax))
10791 AddWet(delta * GameConstants.WETNESS_RATE_WETTING_LIQUID);
10792 // drying
10793 else if (m_VarWet > m_VarWetMin)
10794 AddWet(-1 * delta * GetDryingIncrement("ground") * 2);
10795 }
10796 else
10797 {
10798 // drying on ground or inside non-itembase (car, ...)
10799 if (m_VarWet > m_VarWetMin)
10800 AddWet(-1 * delta * GetDryingIncrement("ground"));
10801 }
10802 }
10803 }
10804
10805 void ProcessItemTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
10806 {
10808 {
10809 float target = g_Game.GetMission().GetWorldData().GetBaseEnvTemperatureAtObject(this);
10810 if (GetTemperature() != target || !IsFreezeThawProgressFinished())
10811 {
10812 float heatPermCoef = 1.0;
10813 EntityAI ent = this;
10814 while (ent)
10815 {
10816 heatPermCoef *= ent.GetHeatPermeabilityCoef();
10817 ent = ent.GetHierarchyParent();
10818 }
10819
10820 SetTemperatureEx(new TemperatureDataInterpolated(target,ETemperatureAccessTypes.ACCESS_WORLD,delta,GameConstants.TEMP_COEF_WORLD,heatPermCoef));
10821 }
10822 }
10823 }
10824
10825 void HierarchyCheck(out bool hasParent, out bool hasRootAsPlayer, out ItemBase refParentIB)
10826 {
10827 // hierarchy check for an item to decide whether it has some parent and it is in some player inventory
10828 EntityAI parent = GetHierarchyParent();
10829 if (!parent)
10830 {
10831 hasParent = false;
10832 hasRootAsPlayer = false;
10833 }
10834 else
10835 {
10836 hasParent = true;
10837 hasRootAsPlayer = (GetHierarchyRootPlayer() != null);
10838 refParentIB = ItemBase.Cast(parent);
10839 }
10840 }
10841
10842 protected void ProcessDecay(float delta, bool hasRootAsPlayer)
10843 {
10844 // this is stub, implemented on Edible_Base
10845 }
10846
10847 bool CanDecay()
10848 {
10849 // return true used on selected food clases so they can decay
10850 return false;
10851 }
10852
10853 protected bool CanProcessDecay()
10854 {
10855 // this is stub, implemented on Edible_Base class
10856 // used to determine whether it is still necessary for the food to decay
10857 return false;
10858 }
10859
10860 protected bool CanHaveWetness()
10861 {
10862 // return true used on selected items that have a wetness effect
10863 return false;
10864 }
10865
10867 bool CanBeConsumed(ConsumeConditionData data = null)
10868 {
10869 return !GetIsFrozen() && IsOpen();
10870 }
10871
10872 override void ProcessVariables()
10873 {
10874 bool hasParent = false, hasRootAsPlayer = false;
10875 ItemBase refParentIB;
10876
10877 bool wwtu = g_Game.IsWorldWetTempUpdateEnabled();
10878 bool foodDecay = g_Game.IsFoodDecayEnabled();
10879
10880 if (wwtu || foodDecay)
10881 {
10882 bool processWetness = wwtu && CanHaveWetness();
10883 bool processTemperature = wwtu && CanHaveTemperature();
10884 bool processDecay = foodDecay && CanDecay() && CanProcessDecay();
10885
10886 if (processWetness || processTemperature || processDecay)
10887 {
10888 HierarchyCheck(hasParent, hasRootAsPlayer, refParentIB);
10889
10890 if (processWetness)
10891 ProcessItemWetness(m_ElapsedSinceLastUpdate, hasParent, hasRootAsPlayer, refParentIB);
10892
10893 if (processTemperature)
10894 ProcessItemTemperature(m_ElapsedSinceLastUpdate, hasParent, hasRootAsPlayer, refParentIB);
10895
10896 if (processDecay)
10897 ProcessDecay(m_ElapsedSinceLastUpdate, hasRootAsPlayer);
10898 }
10899 }
10900 }
10901
10904 {
10905 return m_TemperaturePerQuantityWeight * GameConstants.ITEM_TEMPERATURE_QUANTITY_WEIGHT_MULTIPLIER;
10906 }
10907
10908 override float GetTemperatureFreezeThreshold()
10909 {
10911 return Liquid.GetFreezeThreshold(GetLiquidType());
10912
10913 return super.GetTemperatureFreezeThreshold();
10914 }
10915
10916 override float GetTemperatureThawThreshold()
10917 {
10919 return Liquid.GetThawThreshold(GetLiquidType());
10920
10921 return super.GetTemperatureThawThreshold();
10922 }
10923
10924 override float GetItemOverheatThreshold()
10925 {
10927 return Liquid.GetBoilThreshold(GetLiquidType());
10928
10929 return super.GetItemOverheatThreshold();
10930 }
10931
10932 override float GetTemperatureFreezeTime()
10933 {
10934 if (HasQuantity())
10935 return Math.Lerp(GameConstants.TEMPERATURE_TIME_FREEZE_MIN,Math.Max(GameConstants.TEMPERATURE_TIME_FREEZE_MIN,super.GetTemperatureFreezeTime()),GetQuantityNormalized());
10936
10937 return super.GetTemperatureFreezeTime();
10938 }
10939
10940 override float GetTemperatureThawTime()
10941 {
10942 if (HasQuantity())
10943 return Math.Lerp(GameConstants.TEMPERATURE_TIME_THAW_MIN,Math.Max(GameConstants.TEMPERATURE_TIME_FREEZE_MIN,super.GetTemperatureThawTime()),GetQuantityNormalized());
10944
10945 return super.GetTemperatureThawTime();
10946 }
10947
10949 void AffectLiquidContainerOnFill(int liquid_type, float amount);
10951 void AffectLiquidContainerOnTransfer(int liquidType, float amount, float sourceLiquidTemperature);
10952
10953 bool IsCargoException4x3(EntityAI item)
10954 {
10955 return (item.IsKindOf("Cauldron") || item.IsKindOf("Pot") || item.IsKindOf("FryingPan") || item.IsKindOf("SmallProtectorCase") || (item.IsKindOf("PortableGasStove") && item.FindAttachmentBySlotName("CookingEquipment")));
10956 }
10957
10959 {
10960 MiscGameplayFunctions.TransferItemProperties(oldItem, this);
10961 }
10962
10964 void AddLightSourceItem(ItemBase lightsource)
10965 {
10966 m_LightSourceItem = lightsource;
10967 }
10968
10970 {
10971 m_LightSourceItem = null;
10972 }
10973
10975 {
10976 return m_LightSourceItem;
10977 }
10978
10980 array<int> GetValidFinishers()
10981 {
10982 return null;
10983 }
10984
10986 bool GetActionWidgetOverride(out typename name)
10987 {
10988 return false;
10989 }
10990
10991 bool PairWithDevice(notnull ItemBase otherDevice)
10992 {
10993 if (GetGame().IsServer())
10994 {
10995 ItemBase explosive = otherDevice;
10997 if (!trg)
10998 {
10999 trg = RemoteDetonatorTrigger.Cast(otherDevice);
11000 explosive = this;
11001 }
11002
11003 explosive.PairRemote(trg);
11004 trg.SetControlledDevice(explosive);
11005
11006 int persistentID = RemotelyActivatedItemBehaviour.GeneratePersistentID();
11007 trg.SetPersistentPairID(persistentID);
11008 explosive.SetPersistentPairID(persistentID);
11009
11010 return true;
11011 }
11012 return false;
11013 }
11014
11016 float GetBaitEffectivity()
11017 {
11018 float ret = 1.0;
11019 if (HasQuantity())
11020 ret *= GetQuantityNormalized();
11021 ret *= GetHealth01();
11022
11023 return ret;
11024 }
11025
11026 #ifdef DEVELOPER
11027 override void SetDebugItem()
11028 {
11029 super.SetDebugItem();
11030 _itemBase = this;
11031 }
11032
11033 override string GetDebugText()
11034 {
11035 string text = super.GetDebugText();
11036
11037 text += string.Format("Heat isolation(raw): %1\n", GetHeatIsolation());
11038 text += string.Format("Heat isolation(modified): %1\n", MiscGameplayFunctions.GetCurrentItemHeatIsolation(this));
11039
11040 return text;
11041 }
11042 #endif
11043
11044 bool CanBeUsedForSuicide()
11045 {
11046 return true;
11047 }
11048
11050 //DEPRECATED BELOW
11052 // Backwards compatibility
11053 void ProcessItemWetnessAndTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
11054 {
11055 ProcessItemWetness(delta, hasParent, hasRootAsPlayer, refParentIB);
11056 ProcessItemTemperature(delta, hasParent, hasRootAsPlayer, refParentIB);
11057 }
11058
11059 // replaced by ItemSoundHandler
11060 protected EffectSound m_SoundDeployFinish;
11061 protected EffectSound m_SoundPlace;
11062 protected EffectSound m_DeployLoopSoundEx;
11063 protected EffectSound m_SoundDeploy;
11064 bool m_IsPlaceSound;
11065 bool m_IsDeploySound;
11067
11068 string GetDeployFinishSoundset();
11069 void PlayDeploySound();
11070 void PlayDeployFinishSound();
11071 void PlayPlaceSound();
11072 void PlayDeployLoopSoundEx();
11073 void StopDeployLoopSoundEx();
11074 void SoundSynchRemoteReset();
11075 void SoundSynchRemote();
11076 bool UsesGlobalDeploy(){return false;}
11077 bool CanPlayDeployLoopSound(){return false;}
11079 bool IsPlaceSound(){return m_IsPlaceSound;}
11080 bool IsDeploySound(){return m_IsDeploySound;}
11081 void SetIsPlaceSound(bool is_place_sound);
11082 void SetIsDeploySound(bool is_deploy_sound);
11083}
11084
11085EntityAI SpawnItemOnLocation(string object_name, notnull InventoryLocation loc, bool full_quantity)
11086{
11087 EntityAI entity = SpawnEntity(object_name, loc, ECE_IN_INVENTORY, RF_DEFAULT);
11088 if (entity)
11089 {
11090 bool is_item = entity.IsInherited(ItemBase);
11091 if (is_item && full_quantity)
11092 {
11093 ItemBase item = ItemBase.Cast(entity);
11094 item.SetQuantity(item.GetQuantityInit());
11095 }
11096 }
11097 else
11098 {
11099 ErrorEx("Cannot spawn entity: " + object_name,ErrorExSeverity.INFO);
11100 return NULL;
11101 }
11102 return entity;
11103}
11104
11105void SetupSpawnedItem(ItemBase item, float health, float quantity)
11106{
11107 if (item)
11108 {
11109 if (health > 0)
11110 item.SetHealth("", "", health);
11111
11112 if (item.CanHaveTemperature())
11113 {
11114 item.SetTemperatureDirect(GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_MIDDLE);
11115 if (item.CanFreeze())
11116 item.SetFrozen(false);
11117 }
11118
11119 if (item.HasEnergyManager())
11120 {
11121 if (quantity >= 0)
11122 {
11123 item.GetCompEM().SetEnergy0To1(quantity);
11124 }
11125 else
11126 {
11127 item.GetCompEM().SetEnergy(Math.AbsFloat(quantity));
11128 }
11129 }
11130 else if (item.IsMagazine())
11131 {
11132 Magazine mag = Magazine.Cast(item);
11133 if (quantity >= 0)
11134 {
11135 mag.ServerSetAmmoCount(mag.GetAmmoMax() * quantity);
11136 }
11137 else
11138 {
11139 mag.ServerSetAmmoCount(Math.AbsFloat(quantity));
11140 }
11141
11142 }
11143 else
11144 {
11145 if (quantity >= 0)
11146 {
11147 item.SetQuantityNormalized(quantity, false);
11148 }
11149 else
11150 {
11151 item.SetQuantity(Math.AbsFloat(quantity));
11152 }
11153
11154 }
11155 }
11156}
11157
11158#ifdef DEVELOPER
11159ItemBase _itemBase;//watched item goes here(LCTRL+RMB->Watch)
11160#endif
Param4< int, int, string, int > TSelectableActionInfoWithColor
Определения 3_Game/Entities/EntityAI.c:97
Param3 TSelectableActionInfo
EWetnessLevel
Определения 3_Game/Entities/EntityAI.c:2
InventoryMode
NOTE: PREDICTIVE is not to be used at all in multiplayer.
const int INPUT_UDT_ITEM_MANIPULATION
class LogManager EntityAI
eBleedingSourceType GetType()
ItemSuppressor SuppressorBase
void ActionDropItem()
Определения ActionDropItem.c:14
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
int GetLiquidType()
Определения CCTWaterSurface.c:129
const int ECE_PLACE_ON_SURFACE
Определения CentralEconomy.c:37
proto native void SpawnEntity(string sClassName, vector vPos, float fRange, int iCount)
Spawn an entity through CE.
const int ECE_IN_INVENTORY
Определения CentralEconomy.c:36
const int RF_DEFAULT
Определения CentralEconomy.c:65
PlayerSpawnPresetDiscreteItemSetSlotData name
one set for cargo
PlayerSpawnPreset slotName
Open
Implementations only.
override void EEOnCECreate()
Определения ContaminatedArea_Dynamic.c:42
map
Определения ControlsXboxNew.c:4
CookingMethodType
Определения Cooking.c:2
DamageType
exposed from C++ (do not change)
Определения DamageSystem.c:11
DayZGame g_Game
Определения DayZGame.c:3868
DayZGame GetDayZGame()
Определения DayZGame.c:3870
EActions
Определения EActions.c:2
ERPCs
Определения ERPCs.c:2
PluginAdminLog m_AdminLog
Определения EmoteManager.c:142
const int MAX
Определения EnConvert.c:27
float GetTemperature()
Определения Environment.c:497
override bool IsExplosive()
Определения ExplosivesBase.c:59
override bool CanHaveTemperature()
Определения FireplaceBase.c:559
class GP5GasMask extends MaskBase ItemBase
Empty
Определения Hand_States.c:14
FindInventoryLocationType
flags for searching locations in inventory
Определения InventoryLocation.c:17
InventoryLocationType
types of Inventory Location
Определения InventoryLocation.c:4
class BoxCollidingParams component
ComponentInfo for BoxCollidingResult.
bool DamageItemInCargo(float damage)
Определения ItemBase.c:6380
static bool HasDebugActionsMask(int mask)
Определения ItemBase.c:5620
bool HidesSelectionBySlot()
Определения ItemBase.c:9347
float m_VarWetMin
Определения ItemBase.c:4881
void SplitItem(PlayerBase player)
Определения ItemBase.c:6831
void CopyScriptPropertiesFrom(EntityAI oldItem)
Определения ItemBase.c:9568
override void InsertAgent(int agent, float count=1)
Определения ItemBase.c:8795
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:8229
static void SetDebugActionsMask(int mask)
Определения ItemBase.c:5625
void SetIsDeploySound(bool is_deploy_sound)
bool IsOpen()
Определения ItemBase.c:8938
void SplitItemToInventoryLocation(notnull InventoryLocation dst)
Определения ItemBase.c:6798
override bool IsHeavyBehaviour()
Определения ItemBase.c:9140
override void SetWetMax()
Определения ItemBase.c:8511
bool IsCoverFaceForShave(string slot_name)
DEPRECATED in use, but returns correct values nontheless. Check performed elsewhere.
Определения ItemBase.c:9385
void ClearStartItemSoundServer()
Определения ItemBase.c:9283
float m_VarWet
Определения ItemBase.c:4878
void ProcessItemTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
Определения ItemBase.c:9415
map< typename, ref ActionOverrideData > TActionAnimOverrideMap
Определения ItemBase.c:2
override void RemoveAllAgentsExcept(int agent_to_keep)
Определения ItemBase.c:8790
static ref map< int, ref array< ref WeaponParticlesOnBulletCasingEject > > m_OnBulletCasingEjectEffect
Определения ItemBase.c:4941
bool CanBeMovedOverride()
Определения ItemBase.c:7522
override void SetWet(float value, bool allow_client=false)
Определения ItemBase.c:8487
ref TIntArray m_SingleUseActions
Определения ItemBase.c:4927
override void ProcessVariables()
Определения ItemBase.c:9482
ref TStringArray m_HeadHidingSelections
Определения ItemBase.c:4955
float GetWeightSpecialized(bool forceRecalc=false)
Определения ItemBase.c:8321
bool LoadAgents(ParamsReadContext ctx, int version)
Определения ItemBase.c:8856
void UpdateQuickbarShortcutVisibility(PlayerBase player)
To be called on moving item within character's inventory; 'player' should never be null.
Определения ItemBase.c:8701
void OverrideActionAnimation(typename action, int commandUID, int stanceMask=-1, int commandUIDProne=-1)
Определения ItemBase.c:5211
ref array< ref OverheatingParticle > m_OverheatingParticles
Определения ItemBase.c:4953
override float GetTemperatureFreezeThreshold()
Определения ItemBase.c:9518
bool m_IsSoundSynchRemote
Определения ItemBase.c:9676
float m_OverheatingShots
Определения ItemBase.c:4948
void StopItemSoundServer(int id)
Определения ItemBase.c:9271
static void ToggleDebugActionsMask(int mask)
Определения ItemBase.c:5640
void IncreaseOverheating(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:5364
override float GetTemperatureFreezeTime()
Определения ItemBase.c:9542
ref array< int > m_CompatibleLocks
Определения ItemBase.c:4965
bool CanBeCooked()
Определения ItemBase.c:7478
override void CombineItemsClient(EntityAI entity2, bool use_stack_max=true)
Определения ItemBase.c:5707
float m_TemperaturePerQuantityWeight
Определения ItemBase.c:4977
bool m_RecipesInitialized
Определения ItemBase.c:4863
void SplitIntoStackMax(EntityAI destination_entity, int slot_id, PlayerBase player)
Определения ItemBase.c:6471
override float GetTemperatureThawThreshold()
Определения ItemBase.c:9526
override void OnEnergyConsumed()
Определения ItemBase.c:8431
void RefreshAudioVisualsOnClient(CookingMethodType cooking_method, bool is_done, bool is_empty, bool is_burned)
cooking-related effect methods
Определения Bottle_Base.c:158
int GetNumberOfItems()
Returns the number of items in cargo, otherwise returns 0(non-cargo objects). Recursive.
Определения ItemBase.c:8360
override EWetnessLevel GetWetLevel()
Определения ItemBase.c:8551
float GetSingleInventoryItemWeight()
Определения ItemBase.c:8316
ref TIntArray m_InteractActions
Определения ItemBase.c:4929
void MessageToOwnerStatus(string text)
Send message to owner player in grey color.
Определения ItemBase.c:7542
float m_VarQuantity
Определения ItemBase.c:4869
bool CanPlayDeployLoopSound()
Определения ItemBase.c:9687
override float GetWetMax()
Определения ItemBase.c:8521
bool CanBeUsedForSuicide()
Определения ItemBase.c:9654
override void CombineItemsEx(EntityAI entity2, bool use_stack_max=true)
Определения ItemBase.c:7117
void OnItemInHandsPlayerSwimStart(PlayerBase player)
void SetIsHologram(bool is_hologram)
Определения ItemBase.c:5845
void OnSyncVariables(ParamsReadContext ctx)
DEPRECATED (most likely)
Определения ItemBase.c:7696
void StartItemSoundServer(int id)
Определения ItemBase.c:9258
void DoAmmoExplosion()
Определения ItemBase.c:6315
static ref map< int, ref array< ref WeaponParticlesOnFire > > m_OnFireEffect
Определения ItemBase.c:4940
void SplitIntoStackMaxCargoClient(EntityAI destination_entity, int idx, int row, int col)
Определения ItemBase.c:6655
int GetItemSize()
Определения ItemBase.c:7507
bool m_CanBeMovedOverride
Определения ItemBase.c:4906
override string ChangeIntoOnAttach(string slot)
Определения ItemBase.c:6239
void UpdateOverheating(ItemBase weapon=null, string ammoType="", ItemBase muzzle_owner=null, ItemBase suppressor=null, string config_to_search="")
Определения ItemBase.c:5432
bool CanDecay()
Определения ItemBase.c:9457
ScriptedLightBase GetLight()
string GetPlaceSoundset()
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:8202
void SetQuantityMax()
Определения ItemBase.c:8207
override float GetQuantity()
Определения ItemBase.c:8296
int m_ColorComponentR
Определения ItemBase.c:4918
int m_ShotsToStartOverheating
Определения ItemBase.c:4950
override void OnWetChanged(float newVal, float oldVal)
Определения ItemBase.c:8536
void StopOverheating(ItemBase weapon=null, string ammoType="", ItemBase muzzle_owner=null, ItemBase suppressor=null, string config_to_search="")
Определения ItemBase.c:5439
static void PlayFireParticles(ItemBase weapon, int muzzle_index, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:9039
void OnOverheatingDecay()
Определения ItemBase.c:5402
float GetDryingIncrement(string pIncrementName)
Определения ItemBase.c:8469
void SoundSynchRemoteReset()
int m_Cleanness
Определения ItemBase.c:4884
bool HasMuzzle()
Returns true if this item has a muzzle (weapons, suppressors)
Определения ItemBase.c:5540
bool UsesGlobalDeploy()
Определения ItemBase.c:9686
int m_ItemBehaviour
Определения ItemBase.c:4899
override bool CanReleaseAttachment(EntityAI attachment)
Определения ItemBase.c:9011
float m_HeatIsolation
Определения ItemBase.c:4894
float m_VarWetInit
Определения ItemBase.c:4880
override void OnMovedInsideCargo(EntityAI container)
Определения ItemBase.c:5885
void SetCEBasedQuantity()
Определения ItemBase.c:5653
bool m_CanPlayImpactSound
Определения ItemBase.c:4890
override string GetAttachmentSoundType()
Определения ItemBase.c:9214
float GetOverheatingCoef()
Определения ItemBase.c:5459
array< string > GetHeadHidingSelection()
Определения ItemBase.c:9342
void PlayAttachSound(string slot_type)
Plays sound on item attach. Be advised, the config structure may slightly change in 1....
Определения ItemBase.c:9294
override bool IsStoreLoad()
Определения ItemBase.c:8563
int ComputeQuantityUsed(ItemBase other_item, bool use_stack_max=true)
Определения ItemBase.c:7093
bool IsLightSource()
Определения ItemBase.c:5781
bool m_HasQuantityBar
Определения ItemBase.c:4912
void SetResultOfSplit(bool value)
Определения ItemBase.c:7088
void SplitIntoStackMaxCargo(EntityAI destination_entity, int idx, int row, int col)
Определения ItemBase.c:6719
void OnAttachmentQuantityChanged(ItemBase item)
Called on server side when some attachment's quantity is changed. Call super.OnAttachmentQuantityChan...
Определения ItemBase.c:6889
void UpdateAllOverheatingParticles()
Определения ItemBase.c:5467
float GetSoakingIncrement(string pIncrementName)
Определения ItemBase.c:8478
static void StopOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:9119
override float GetStoreLoadedQuantity()
Определения ItemBase.c:8573
int m_LockType
Определения ItemBase.c:4966
const int ITEM_SOUNDS_MAX
Определения ItemBase.c:4971
bool m_CanBeDigged
Определения ItemBase.c:4913
float m_ItemAttachOffset
Определения ItemBase.c:4896
float GetItemModelLength()
Определения ItemBase.c:8580
bool m_ThrowItemOnDrop
Определения ItemBase.c:4904
override bool ReadVarsFromCTX(ParamsReadContext ctx, int version=-1)
Определения ItemBase.c:7841
override void CheckForRoofLimited(float timeTresholdMS=3000)
Roof check for entity, limited by time (anti-spam solution)
Определения ItemBase.c:8871
void Close()
float GetHeatIsolation()
Определения ItemBase.c:8464
void CombineItems(ItemBase other_item, bool use_stack_max=true)
Определения ItemBase.c:7122
void TransferModifiers(PlayerBase reciever)
appears to be deprecated, legacy code
float GetTemperaturePerQuantityWeight()
Used in heat comfort calculations only!
Определения ItemBase.c:9513
bool CanHaveWetness()
Определения ItemBase.c:9470
int m_CleannessMin
Определения ItemBase.c:4886
void TransferAgents(int agents)
transfer agents from another item
Определения ItemBase.c:8804
string IDToName(int id)
Определения ItemBase.c:7689
bool CanBeConsumed(ConsumeConditionData data=null)
Items cannot be consumed if frozen by default. Override for exceptions.
Определения ItemBase.c:9477
float GetHeatIsolationInit()
Определения ItemBase.c:8459
void PlayPlaceSound()
void SetCanBeMovedOverride(bool setting)
Определения ItemBase.c:7529
override bool HasQuantity()
Определения ItemBase.c:8291
float m_VarWetPrev
Определения ItemBase.c:4879
int m_SoundSyncStop
Определения ItemBase.c:4973
bool IsCargoException4x3(EntityAI item)
Определения ItemBase.c:9563
ref TIntArray m_ContinuousActions
Определения ItemBase.c:4928
int GetMuzzleID()
Returns global muzzle ID. If not found, then it gets automatically registered.
Определения ItemBase.c:5549
void LoadParticleConfigOnFire(int id)
Определения ItemBase.c:5234
int m_VarLiquidType
Определения ItemBase.c:4898
int m_QuickBarBonus
Определения ItemBase.c:4900
void PreLoadSoundAttachmentType()
Attachment Sound Type getting from config file.
Определения ItemBase.c:9202
override float GetWetInit()
Определения ItemBase.c:8531
int m_ImpactSoundSurfaceHash
Определения ItemBase.c:4892
int m_SoundSyncPlay
Определения ItemBase.c:4972
int m_MaxOverheatingValue
Определения ItemBase.c:4951
void SetupSpawnedItem(ItemBase item, float health, float quantity)
Определения ItemBase.c:4875
bool m_IsTakeable
Определения ItemBase.c:4903
bool ShouldSplitQuantity(float quantity)
Определения ItemBase.c:6428
static ref map< string, int > m_WeaponTypeToID
Определения ItemBase.c:4943
string GetLockSoundSet()
Определения ItemBase.c:8629
string GetColorString()
Returns item's PROCEDURAL color as formated string, i.e. "#(argb,8,8,3)color(0.15,...
Определения ItemBase.c:8660
array< int > GetValidFinishers()
returns an array of possible finishers
Определения ItemBase.c:9590
void OnAttachmentQuantityChangedEx(ItemBase item, float delta)
Called on server side when some attachment's quantity is changed. Call super.OnAttachmentQuantityChan...
Определения ItemBase.c:6895
class ItemBase extends InventoryItem SpawnItemOnLocation(string object_name, notnull InventoryLocation loc, bool full_quantity)
Определения ItemBase.c:4855
ItemSoundHandler GetItemSoundHandler()
Определения ItemBase.c:9229
override int GetQuantityMin()
Определения ItemBase.c:8280
void SplitIntoStackMaxToInventoryLocationClient(notnull InventoryLocation dst)
Определения ItemBase.c:6634
override int GetQuickBarBonus()
Определения ItemBase.c:5119
override void SetTakeable(bool pState)
Определения ItemBase.c:9184
float m_OverheatingDecayInterval
Определения ItemBase.c:4952
void SetIsPlaceSound(bool is_place_sound)
override void SplitIntoStackMaxClient(EntityAI destination_entity, int slot_id)
Определения ItemBase.c:6448
void HierarchyCheck(out bool hasParent, out bool hasRootAsPlayer, out ItemBase refParentIB)
Определения ItemBase.c:9435
bool CanProcessDecay()
Определения ItemBase.c:9463
void RemoveAudioVisualsOnClient()
Определения Bottle_Base.c:151
void SoundSynchRemote()
static void AddDebugActionsMask(int mask)
Определения ItemBase.c:5630
void PlayDeployLoopSoundEx()
void RemoveLightSourceItem()
Определения ItemBase.c:9579
bool CanRepair(ItemBase item_repair_kit)
Определения ItemBase.c:7493
bool can_this_be_combined
Определения ItemBase.c:4908
EffectSound m_SoundDeploy
Определения ItemBase.c:9673
int m_Count
Определения ItemBase.c:4874
float GetBaitEffectivity()
generic effectivity as a bait for animal catching
Определения ItemBase.c:9626
float GetDeployTime()
how long it takes to deploy this item in seconds
Определения ItemBase.c:9176
override bool IsSplitable()
Определения ItemBase.c:6415
bool DamageItemAttachments(float damage)
Определения ItemBase.c:6399
override void WriteVarsToCTX(ParamsWriteContext ctx)
Определения ItemBase.c:7805
void ConvertEnergyToQuantity()
Определения ItemBase.c:8446
override void RemoveAllAgents()
Определения ItemBase.c:8785
override void SetQuantityToMinimum()
Определения ItemBase.c:8213
bool m_WantPlayImpactSound
Определения ItemBase.c:4889
override float GetTemperatureThawTime()
Определения ItemBase.c:9550
ref map< int, ref array< ref WeaponParticlesOnOverheating > > m_OnOverheatingEffect
Определения ItemBase.c:4942
int m_ColorComponentG
Определения ItemBase.c:4919
float m_StoreLoadedQuantity
Определения ItemBase.c:4876
void MessageToOwnerAction(string text)
Send message to owner player in yellow color.
Определения ItemBase.c:7560
int m_ColorComponentA
Определения ItemBase.c:4921
int m_VarQuantityInit
Определения ItemBase.c:4871
float GetFilterDamageRatio()
Определения ItemBase.c:5534
override void SetLiquidType(int value, bool allow_client=false)
Определения ItemBase.c:8673
void OnQuantityChanged(float delta)
Called on server side when this item's quantity is changed. Call super.OnQuantityChanged(); first whe...
Определения ItemBase.c:6865
void OnApply(PlayerBase player)
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:8220
bool m_HideSelectionsBySlot
Определения ItemBase.c:4956
bool IsOverheatingEffectActive()
Определения ItemBase.c:5397
void SetIsBeingPlaced(bool is_being_placed)
Определения ItemBase.c:5814
int GetLiquidContainerMask()
Определения ItemBase.c:5751
void SetInventoryLocationToVicinityOrCurrent(EntityAI root, inout InventoryLocation dst)
Определения ItemBase.c:7002
ref Timer m_CheckOverheating
Определения ItemBase.c:4949
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:5445
float GetEnergy()
Определения ItemBase.c:8420
bool CanBeDigged()
Определения ItemBase.c:5830
bool GetActionWidgetOverride(out typename name)
If we need a different (handheld)item action widget displayed, the logic goes in here.
Определения ItemBase.c:9596
bool IsNVG()
Определения ItemBase.c:5762
float GetUnitWeight(bool include_wetness=true)
Obsolete, use GetWeightEx instead.
Определения ItemBase.c:8380
void SetZoneDamageCEInit()
Sets zone damages to match randomized global health set by CE (CE spawn only)
Определения ItemBase.c:9372
bool m_IsDeploySound
Определения ItemBase.c:9675
bool CanEat()
Определения ItemBase.c:7453
static void PlayOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:9079
override bool IsOneHandedBehaviour()
Определения ItemBase.c:9150
void AddLightSourceItem(ItemBase lightsource)
Adds a light source child.
Определения ItemBase.c:9574
bool IsLiquidContainer()
Определения ItemBase.c:5746
FoodStage GetFoodStage()
overridden on Edible_Base; so we don't have to parse configs all the time
Определения ItemBase.c:7473
override float GetSingleInventoryItemWeightEx()
Определения ItemBase.c:8307
void SaveAgents(ParamsWriteContext ctx)
Определения ItemBase.c:8863
override int GetTargetQuantityMax(int attSlotID=-1)
Определения ItemBase.c:8261
int m_CleannessInit
Определения ItemBase.c:4885
float GetDisinfectQuantity(int system=0, Param param1=null)
Определения ItemBase.c:5529
override int GetAgents()
Определения ItemBase.c:8810
int m_VarQuantityMax
Определения ItemBase.c:4873
override bool IsHologram()
Определения ItemBase.c:5825
float GetItemAttachOffset()
Определения ItemBase.c:8589
bool IsPlaceSound()
Определения ItemBase.c:9689
static int GetDebugActionsMask()
Определения ItemBase.c:5615
void ProcessDecay(float delta, bool hasRootAsPlayer)
Определения ItemBase.c:9452
override bool IsItemBase()
Определения ItemBase.c:7606
void PlayDeploySound()
override bool IsTwoHandedBehaviour()
Определения ItemBase.c:9160
void ExplodeAmmo()
Определения ItemBase.c:6302
bool IsCombineAll(ItemBase other_item, bool use_stack_max=false)
Определения ItemBase.c:7078
float GetProtectionLevel(int type, bool consider_filter=false, int system=0)
Определения ItemBase.c:8884
static void PlayBulletCasingEjectParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:9059
override void OnEnergyAdded()
Определения ItemBase.c:8438
void AffectLiquidContainerOnFill(int liquid_type, float amount)
from enviro source
void AffectLiquidContainerOnTransfer(int liquidType, float amount, float sourceLiquidTemperature)
from other liquid container source
string GetExplosiveTriggerSlotName()
Определения ItemBase.c:5774
EffectSound m_DeployLoopSoundEx
Определения ItemBase.c:9672
override void DeSerializeNumericalVars(array< float > floats)
Определения ItemBase.c:7746
void StopItemDynamicPhysics()
Определения ItemBase.c:9354
bool HasFoodStage()
Определения ItemBase.c:7466
override void SetStoreLoad(bool value)
Определения ItemBase.c:8558
float GetOverheatingValue()
Определения ItemBase.c:5359
bool ContainsAgent(int agent_id)
Определения ItemBase.c:8763
override void AddWet(float value)
Определения ItemBase.c:8506
bool IsLiquidPresent()
Определения ItemBase.c:5741
bool IsFullQuantity()
Определения ItemBase.c:8301
override void EOnContact(IEntity other, Contact extra)
Определения ItemBase.c:6015
void SplitIntoStackMaxHands(PlayerBase player)
Определения ItemBase.c:6770
void SplitIntoStackMaxHandsClient(PlayerBase player)
Определения ItemBase.c:6746
int m_CleannessMax
Определения ItemBase.c:4887
float m_VarStackMax
Определения ItemBase.c:4875
ref Timer m_PhysDropTimer
Определения ItemBase.c:4962
void MessageToOwnerFriendly(string text)
Send message to owner player in green color.
Определения ItemBase.c:7578
override void SetStoreLoadedQuantity(float value)
Определения ItemBase.c:8568
bool m_IsResultOfSplit string m_SoundAttType
distinguish if item has been created as new or it came from splitting (server only flag)
Определения ItemBase.c:4916
void CheckOverheating(ItemBase weapon=null, string ammoType="", ItemBase muzzle_owner=null, ItemBase suppressor=null, string config_to_search="")
Определения ItemBase.c:5380
void UnlockFromParent()
Unlocks this item from its attachment slot of its parent.
Определения ItemBase.c:5695
bool Repair(PlayerBase player, ItemBase item_repair_kit, float specialty_weight)
Определения ItemBase.c:7500
void OnLiquidTypeChanged(int oldType, int newType)
Определения ItemBase.c:8694
void StartOverheating(ItemBase weapon=null, string ammoType="", ItemBase muzzle_owner=null, ItemBase suppressor=null, string config_to_search="")
Определения ItemBase.c:5426
void PlayDeployFinishSound()
bool AllowFoodConsumption()
Определения ItemBase.c:8616
bool m_IsOverheatingEffectActive
Определения ItemBase.c:4947
int m_LiquidContainerMask
Определения ItemBase.c:4897
void ProcessItemWetness(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
Определения ItemBase.c:9390
override int GetCleanness()
Определения ItemBase.c:8611
bool PairWithDevice(notnull ItemBase otherDevice)
Определения ItemBase.c:9601
bool IsDeploySound()
Определения ItemBase.c:9690
static void RemoveDebugActionsMask(int mask)
Определения ItemBase.c:5635
static void UpdateOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:9099
int m_VarQuantityMin
Определения ItemBase.c:4872
void PerformDamageSystemReinit()
Определения ItemBase.c:9360
override void ClearInventory()
Определения ItemBase.c:8399
static int m_LastRegisteredWeaponID
Определения ItemBase.c:4944
ItemBase GetLightSourceItem()
Определения ItemBase.c:9584
void MessageToOwnerImportant(string text)
Send message to owner player in red color.
Определения ItemBase.c:7596
override float GetItemOverheatThreshold()
Определения ItemBase.c:9534
void StopDeployLoopSoundEx()
bool m_CanThisBeSplit
Определения ItemBase.c:4909
override void SerializeNumericalVars(array< float > floats_out)
Определения ItemBase.c:7710
ItemBase SplitIntoStackMaxToInventoryLocationEx(notnull InventoryLocation dst)
Определения ItemBase.c:6685
float m_ItemModelLength
Определения ItemBase.c:4895
bool m_IsHologram
Определения ItemBase.c:4902
static int m_DebugActionsMask
Определения ItemBase.c:4862
void KillAllOverheatingParticles()
Определения ItemBase.c:5495
bool CanBeCookedOnStick()
Определения ItemBase.c:7483
override int GetQuantityMax()
Определения ItemBase.c:8248
void GetRecipesActions(Man player, out TSelectableActionInfoArray outputList)
Определения ItemBase.c:7156
void OnActivatedByTripWire()
bool IsColorSet()
Определения ItemBase.c:8654
override void RemoveAgent(int agent_id)
Определения ItemBase.c:8776
bool m_ItemBeingDroppedPhys
Определения ItemBase.c:4905
override bool CanPutAsAttachment(EntityAI parent)
Определения ItemBase.c:8966
void PlayDetachSound(string slot_type)
Определения ItemBase.c:9330
static ref map< typename, ref TInputActionMap > m_ItemTypeActionsMap
Определения ItemBase.c:4856
void ProcessItemWetnessAndTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
Определения ItemBase.c:9663
override bool IsBeingPlaced()
Определения ItemBase.c:5809
int GetQuantityInit()
Определения ItemBase.c:8285
float ComputeQuantityUsedEx(ItemBase other_item, bool use_stack_max=true)
Определения ItemBase.c:7098
bool IsResultOfSplit()
Определения ItemBase.c:7083
bool m_FixDamageSystemInit
Определения ItemBase.c:4907
float m_ImpactSpeed
Определения ItemBase.c:4891
bool m_IsStoreLoad
Определения ItemBase.c:4910
int GetLiquidTypeInit()
Определения ItemBase.c:8684
string GetDeployFinishSoundset()
ItemBase m_LightSourceItem
Определения ItemBase.c:4925
void LockToParent()
Locks this item in it's current attachment slot of its parent. This makes the "locked" icon visible i...
Определения ItemBase.c:5682
override void SplitIntoStackMaxEx(EntityAI destination_entity, int slot_id)
Определения ItemBase.c:6557
int m_AttachedAgents
Определения ItemBase.c:4933
string m_LockSoundSet
Определения ItemBase.c:4968
void LoadParticleConfigOnOverheating(int id)
Определения ItemBase.c:5303
float m_VarQuantityPrev
Определения ItemBase.c:4870
bool IsSoundSynchRemote()
Определения ItemBase.c:9688
bool m_CanShowQuantity
Определения ItemBase.c:4911
override void OnRightClick()
Определения ItemBase.c:6938
int m_ColorComponentB
Определения ItemBase.c:4920
static ref map< typename, ref TActionAnimOverrideMap > m_ItemActionOverrides
Определения ItemBase.c:4858
bool IsActionTargetVisible()
Определения ItemBase.c:9196
override void OnItemAttachmentSlotChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
Определения ItemBase.c:6050
override void EEHitBy(TotalDamageResult damageResult, int damageType, EntityAI source, int component, string dmgZone, string ammo, vector modelPos, float speedCoef)
Определения ItemBase.c:6339
bool m_IsBeingPlaced
Определения ItemBase.c:4901
int NameToID(string name)
Определения ItemBase.c:7683
void ~ItemBase()
Определения ItemBase.c:5580
override void OnWetLevelChanged(EWetnessLevel newLevel, EWetnessLevel oldLevel)
Определения ItemBase.c:8546
void ClearStopItemSoundServer()
Определения ItemBase.c:9288
override string ChangeIntoOnDetach()
Определения ItemBase.c:6263
float m_VarWetMax
Определения ItemBase.c:4882
void SplitIntoStackMaxToInventoryLocation(notnull InventoryLocation dst)
Определения ItemBase.c:6680
int GetLockType()
Определения ItemBase.c:8624
EffectSound m_SoundDeployFinish
Определения ItemBase.c:9670
override float GetWet()
Определения ItemBase.c:8516
EffectSound m_SoundPlace
Определения ItemBase.c:9671
float GetQuantityNormalizedScripted()
Определения ItemBase.c:8234
override void SetCleanness(int value, bool allow_client=false)
Определения ItemBase.c:8598
bool m_IsPlaceSound
Определения ItemBase.c:9674
override float GetWetMin()
Определения ItemBase.c:8526
ref ItemSoundHandler m_ItemSoundHandler
Определения ItemBase.c:4974
override bool KindOf(string tag)
Определения ItemBase.c:7612
void ItemSoundHandler(ItemBase parent)
Определения ItemSoundHandler.c:31
string Type
Определения JsonDataContaminatedArea.c:11
EffectSound m_LockingSound
Определения Land_Underground_Entrance.c:321
string GetDebugText()
Определения ModifierBase.c:71
PlayerBase GetPlayer()
Определения ModifierBase.c:51
@ LOWEST
Определения PPEConstants.c:54
void PluginItemDiagnostic()
Определения PluginItemDiagnostic.c:74
PluginBase GetPlugin(typename plugin_type)
Определения PluginManager.c:316
EntityAI GetItem()
Определения RadialQuickbarMenu.c:37
override RemotelyActivatedItemBehaviour GetRemotelyActivatedItemBehaviour()
Определения RemoteDetonator.c:272
void RemoteDetonatorTrigger()
Определения RemoteDetonator.c:233
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
void Debug()
Определения UniversalTemperatureSource.c:349
int GetID()
Определения ActionBase.c:1360
void OnItemLocationChanged(ItemBase item)
Определения ActionBase.c:998
GetInputType()
Определения ActionBase.c:215
int m_StanceMask
Определения ActionBase.c:25
int m_CommandUIDProne
Определения ActionBase.c:24
int m_CommandUID
Определения ActionBase.c:23
void OnItemAttachedAtPlayer(EntityAI item, string slot_name)
Определения AnalyticsManagerClient.c:77
proto native UIManager GetUIManager()
proto bool ConfigGetChildName(string path, int index, out string name)
Get name of subclass in config class on path.
proto native float ConfigGetFloat(string path)
Get float value from config on path.
override ScriptCallQueue GetCallQueue(int call_category)
Определения DayZGame.c:1187
proto native void GizmoSelectObject(Object object)
proto native bool ConfigIsExisting(string path)
proto native void ConfigGetTextArray(string path, out TStringArray values)
Get array of strings from config on path.
proto native DayZPlayer GetPlayer()
proto native void GizmoSelectPhysics(Physics physics)
proto int GetTime()
returns mission time in milliseconds
proto native int ConfigGetType(string path)
Returns type of config value.
AnalyticsManagerClient GetAnalyticsClient()
Определения Global/game.c:1568
proto native int ConfigGetChildrenCount(string path)
Get count of subclasses in config class on path.
proto native SoundOnVehicle CreateSoundOnObject(Object source, string sound_name, float distance, bool looped, bool create_local=false)
proto native void ObjectDelete(Object obj)
proto native int GetItemCount()
proto native EntityAI GetItem(int index)
float GetEnergyAtSpawn()
Определения ComponentEnergyManager.c:1280
void SetEnergy0To1(float energy01)
Energy manager: Sets stored energy for this device between 0 and MAX based on relative input value be...
Определения ComponentEnergyManager.c:541
float GetEnergyMaxPristine()
Energy manager: Returns the maximum amount of energy this device can store. It's damage is NOT taken ...
Определения ComponentEnergyManager.c:1275
override void SetAutodestroy(bool auto_destroy)
Sets whether Effect automatically cleans up when it stops.
Определения EffectSound.c:603
bool IsSoundPlaying()
Get whether EffectSound is currently playing.
Определения EffectSound.c:274
override bool IsMan()
Определения 3_Game/Entities/Man.c:44
proto native bool EnumerateInventory(InventoryTraversalType tt, out array< EntityAI > items)
enumerate inventory using traversal type and filling items array
proto native CargoBase GetCargo()
cargo
Определения ItemBase.c:15
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:469
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:29
override bool CanDisplayCargo()
Определения UndergroundStash.c:24
override void OnInventoryEnter(Man player)
Определения BarbedWire.c:203
override string GetFoldSoundset()
Определения BaseBuildingBase.c:108
override bool CanPutAsAttachment(EntityAI parent)
Определения ItemBase.c:6
override bool CanReceiveItemIntoCargo(EntityAI item)
Определения TentBase.c:913
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:68
override bool CanBeRepairedByCrafting()
Определения TentBase.c:86
override void OnPlacementStarted(Man player)
Определения BatteryCharger.c:376
override void OnItemLocationChanged(EntityAI old_owner, EntityAI new_owner)
Определения BarbedWire.c:357
override bool IsElectricAppliance()
Определения BatteryCharger.c:43
override bool IsItemTent()
Определения TentBase.c:81
override void SetActions()
override string GetLoopFoldSoundset()
Определения BaseBuildingBase.c:113
override bool CanMakeGardenplot()
Определения FieldShovel.c:3
override void GetDebugActions(out TSelectableActionInfoArrayEx outputList)
Определения PowerGenerator.c:412
override void EEItemLocationChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
Определения HandcuffsLocked.c:12
override WrittenNoteData GetWrittenNoteData()
Определения Paper.c:30
override int GetDamageSystemVersionChange()
Определения BaseBuildingBase.c:1238
override bool SetQuantity(float value, bool destroy_config=true, bool destroy_forced=false, bool allow_client=false, bool clamp_to_stack_max=true)
Определения PileOfWoodenPlanks.c:88
override void InitItemVariables()
Определения Matchbox.c:3
override void SetActionAnimOverrides()
Определения PickAxe.c:28
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:424
override void EEHealthLevelChanged(int oldLevel, int newLevel, string zone)
Определения BaseBuildingBase.c:496
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:287
override bool IsPlayerInside(PlayerBase player, string selection)
Определения BaseBuildingBase.c:1037
override void OnVariablesSynchronized()
Определения GardenBase.c:97
override void RefreshPhysics()
Определения BatteryCharger.c:359
override bool CanObstruct()
Определения BaseBuildingBase.c:84
override void OnWasAttached(EntityAI parent, int slot_id)
override bool CanReceiveAttachment(EntityAI attachment, int slotId)
Определения BaseBuildingBase.c:982
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:341
override bool IsTakeable()
Определения BaseBuildingBase.c:1008
override bool IsIgnoredByConstruction()
Определения BaseBuildingBase.c:1170
override void InitItemSounds()
Определения BaseBuildingBase.c:94
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:1032
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 IsClothing()
override bool CanBeSplit()
Определения Rag.c:34
override bool IsDeployable()
Определения BaseBuildingBase.c:365
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
Определения EnMath.c:7
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
void Stop()
Legacy function for backwards compatibility with 1.14 and below.
Определения Particle.c:266
void SetControlledDevice(EntityAI pDevice)
Определения RemoteDetonator.c:140
bool OnStoreLoad(ParamsReadContext ctx, int version)
void OnStoreSave(ParamsWriteContext ctx)
proto void Remove(func fn)
remove specific call from queue
proto void CallLater(func fn, int delay=0, bool repeat=false, void param1=NULL, void param2=NULL, void param3=NULL, void param4=NULL, void param5=NULL, void param6=NULL, void param7=NULL, void param8=NULL, void param9=NULL)
adds call into the queue with given parameters and arguments (arguments are held in memory until the ...
proto native void Send()
proto bool Write(void value_out)
proto bool Read(void value_in)
bool m_Loop
Определения ItemSoundHandler.c:5
override void Stop()
Определения DayZPlayerImplement.c:64
proto native float GetDamage(string zoneName, string healthType)
UIScriptedMenu FindMenu(int id)
Returns menu with specific ID if it is open (see MenuID)
Определения UIManager.c:160
override void Refresh()
Определения ChatInputMenu.c:70
void SetCalcDetails(string details)
Определения 3_Game/tools/Debug.c:816
void OnRPC(PlayerIdentity sender, int rpc_type, ParamsReadContext ctx)
Определения WrittenNoteData.c:13
const float LOWEST
Определения EnConvert.c:100
Serializer ParamsReadContext
Определения gameplay.c:15
class LOD Object
InventoryTraversalType
tree traversal type, for more see http://en.wikipedia.org/wiki/Tree_traversal
Определения gameplay.c:6
proto native CGame GetGame()
Serializer ParamsWriteContext
Определения gameplay.c:16
const int DEF_BIOLOGICAL
Определения 3_Game/constants.c:512
const int DEF_CHEMICAL
Определения 3_Game/constants.c:513
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)
array< string > TStringArray
Определения EnScript.c:709
array< int > TIntArray
Определения EnScript.c:711
EntityEvent
Entity events for event-mask, or throwing event from code.
Определения EnEntity.c:45
static const float ITEM_TEMPERATURE_NEUTRAL_ZONE_MIDDLE
Определения 3_Game/constants.c:808
const int VARIABLE_LIQUIDTYPE
Определения 3_Game/constants.c:632
const int VARIABLE_CLEANNESS
Определения 3_Game/constants.c:635
const int VARIABLE_COLOR
Определения 3_Game/constants.c:634
const int VARIABLE_TEMPERATURE
Определения 3_Game/constants.c:630
const int VARIABLE_QUANTITY
Определения 3_Game/constants.c:628
const int VARIABLE_WET
Определения 3_Game/constants.c:631
const int LIQUID_NONE
Определения 3_Game/constants.c:529
static proto float AbsFloat(float f)
Returns absolute value.
const int MENU_INVENTORY
Определения 3_Game/constants.c:180
proto native bool dBodyIsDynamic(notnull IEntity ent)
const int SAT_CRAFTING
Определения 3_Game/constants.c:453
const int SAT_DEBUG_ACTION
Определения 3_Game/constants.c:454
class JsonUndergroundAreaTriggerData GetPosition
Определения UndergroundAreaLoader.c:9
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/tools/tools.c:10
const int CALL_CATEGORY_SYSTEM
Определения 3_Game/tools/tools.c:8
proto native int GetColor()