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

◆ ShouldSplitQuantity()

bool SpawnItemOnLocation::ShouldSplitQuantity ( float quantity)
protected

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

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

Используется в InventoryItem::SplitIntoStackMax(), InventoryItem::SplitIntoStackMaxCargo(), InventoryItem::SplitIntoStackMaxEx(), InventoryItem::SplitIntoStackMaxHands(), InventoryItem::SplitIntoStackMaxToInventoryLocationEx(), InventoryItem::SplitItem() и InventoryItem::SplitItemToInventoryLocation().