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

◆ HasMuzzle()

bool SpawnItemOnLocation::HasMuzzle ( )
private

Returns true if this item has a muzzle (weapons, suppressors)

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

5605{
5606 override bool CanPutAsAttachment(EntityAI parent)
5607 {
5608 return true;
5609 }
5610};
5611
5613{
5614
5615};
5616
5617//const bool QUANTITY_DEBUG_REMOVE_ME = false;
5618
5619class ItemBase extends InventoryItem
5620{
5624
5626
5627 static int m_DebugActionsMask;
5629 // ============================================
5630 // Variable Manipulation System
5631 // ============================================
5632 // Quantity
5633
5634 float m_VarQuantity;
5635 float m_VarQuantityPrev;//for client to know quantity changed during synchronization
5637 int m_VarQuantityMin;
5638 int m_VarQuantityMax;
5639 int m_Count;
5640 float m_VarStackMax;
5641 float m_StoreLoadedQuantity = float.LOWEST;
5642 // Wet
5643 float m_VarWet;
5644 float m_VarWetPrev;//for client to know wetness changed during synchronization
5645 float m_VarWetInit;
5646 float m_VarWetMin;
5647 float m_VarWetMax;
5648 // Cleanness
5649 int m_Cleanness;
5650 int m_CleannessInit;
5651 int m_CleannessMin;
5652 int m_CleannessMax;
5653 // impact sounds
5655 bool m_CanPlayImpactSound = true;
5656 float m_ImpactSpeed;
5658 //
5659 float m_HeatIsolation;
5660 float m_ItemModelLength;
5661 float m_ItemAttachOffset; // Offset length for when the item is attached e.g. to weapon
5663 int m_VarLiquidType;
5664 int m_ItemBehaviour; // -1 = not specified; 0 = heavy item; 1= onehanded item; 2 = twohanded item
5665 int m_QuickBarBonus;
5666 bool m_IsBeingPlaced;
5667 bool m_IsHologram;
5668 bool m_IsTakeable;
5669 bool m_ThrowItemOnDrop;
5672 bool m_FixDamageSystemInit = false; //can be changed on storage version check
5673 bool can_this_be_combined; //Check if item can be combined
5674 bool m_CanThisBeSplit; //Check if item can be split
5675 bool m_IsStoreLoad = false;
5676 bool m_CanShowQuantity;
5677 bool m_HasQuantityBar;
5678 protected bool m_CanBeDigged;
5679 protected bool m_IsResultOfSplit
5680
5681 string m_SoundAttType;
5682 // items color variables
5687 //-------------------------------------------------------
5688
5689 // light source managing
5691
5695
5696 //==============================================
5697 // agent system
5698 private int m_AttachedAgents;
5699
5701 void TransferModifiers(PlayerBase reciever);
5702
5703
5704 // Weapons & suppressors particle effects
5708 ref static map<string, int> m_WeaponTypeToID;
5709 static int m_LastRegisteredWeaponID = 0;
5710
5711 // Overheating effects
5713 float m_OverheatingShots;
5714 ref Timer m_CheckOverheating;
5715 int m_ShotsToStartOverheating = 0; // After these many shots, the overheating effect begins
5716 int m_MaxOverheatingValue = 0; // Limits the number of shots that will be tracked
5717 float m_OverheatingDecayInterval = 1; // Timer's interval for decrementing overheat effect's lifespan
5718 ref array <ref OverheatingParticle> m_OverheatingParticles;
5719
5721 protected bool m_HideSelectionsBySlot;
5722
5723 // Admin Log
5724 PluginAdminLog m_AdminLog;
5725
5726 // misc
5727 ref Timer m_PhysDropTimer;
5728
5729 // Attachment Locking variables
5730 ref array<int> m_CompatibleLocks;
5731 protected int m_LockType;
5732 protected ref EffectSound m_LockingSound;
5733 protected string m_LockSoundSet;
5734
5735 // ItemSoundHandler variables
5736 protected const int ITEM_SOUNDS_MAX = 63; // optimize network synch
5737 protected int m_SoundSyncPlay; // id for sound to play
5738 protected int m_SoundSyncStop; // id for sound to stop
5739 protected int m_SoundSyncSlotID = InventorySlots.INVALID; // slot id for attach/detach sound based on slot
5740
5742
5743 //temperature
5744 private float m_TemperaturePerQuantityWeight;
5745
5746 // -------------------------------------------------------------------------
5747 void ItemBase()
5748 {
5749 SetEventMask(EntityEvent.INIT); // Enable EOnInit event
5753
5754 if (!g_Game.IsDedicatedServer())
5755 {
5756 if (HasMuzzle())
5757 {
5759
5761 {
5763 }
5764 }
5765
5767 m_ActionsInitialize = false;
5768 }
5769
5770 m_OldLocation = null;
5771
5772 if (g_Game.IsServer())
5773 {
5774 m_AdminLog = PluginAdminLog.Cast(GetPlugin(PluginAdminLog));
5775 }
5776
5777 if (ConfigIsExisting("headSelectionsToHide"))
5778 {
5780 ConfigGetTextArray("headSelectionsToHide",m_HeadHidingSelections);
5781 }
5782
5783 m_HideSelectionsBySlot = false;
5784 if (ConfigIsExisting("hideSelectionsByinventorySlot"))
5785 {
5786 m_HideSelectionsBySlot = ConfigGetBool("hideSelectionsByinventorySlot");
5787 }
5788
5789 m_QuickBarBonus = Math.Max(0, ConfigGetInt("quickBarBonus"));
5790
5791 m_IsResultOfSplit = false;
5792
5794 }
5795
5796 override void InitItemVariables()
5797 {
5798 super.InitItemVariables();
5799
5800 m_VarQuantityInit = ConfigGetInt("varQuantityInit");
5801 m_VarQuantity = m_VarQuantityInit;//should be by the CE, this is just a precaution
5802 m_VarQuantityMin = ConfigGetInt("varQuantityMin");
5803 m_VarQuantityMax = ConfigGetInt("varQuantityMax");
5804 m_VarStackMax = ConfigGetFloat("varStackMax");
5805 m_Count = ConfigGetInt("count");
5806
5807 m_CanShowQuantity = ConfigGetBool("quantityShow");
5808 m_HasQuantityBar = ConfigGetBool("quantityBar");
5809
5810 m_CleannessInit = ConfigGetInt("varCleannessInit");
5812 m_CleannessMin = ConfigGetInt("varCleannessMin");
5813 m_CleannessMax = ConfigGetInt("varCleannessMax");
5814
5815 m_WantPlayImpactSound = false;
5816 m_ImpactSpeed = 0.0;
5817
5818 m_VarWetInit = ConfigGetFloat("varWetInit");
5820 m_VarWetMin = ConfigGetFloat("varWetMin");
5821 m_VarWetMax = ConfigGetFloat("varWetMax");
5822
5823 m_LiquidContainerMask = ConfigGetInt("liquidContainerType");
5824 if (IsLiquidContainer() && GetQuantity() != 0)
5826 m_IsBeingPlaced = false;
5827 m_IsHologram = false;
5828 m_IsTakeable = true;
5829 m_CanBeMovedOverride = false;
5833 m_CanBeDigged = ConfigGetBool("canBeDigged");
5834
5835 m_CompatibleLocks = new array<int>();
5836 ConfigGetIntArray("compatibleLocks", m_CompatibleLocks);
5837 m_LockType = ConfigGetInt("lockType");
5838
5839 //Define if item can be split and set ability to be combined accordingly
5840 m_CanThisBeSplit = false;
5841 can_this_be_combined = false;
5842 if (ConfigIsExisting("canBeSplit"))
5843 {
5844 can_this_be_combined = ConfigGetBool("canBeSplit");
5846 }
5847
5848 m_ItemBehaviour = -1;
5849 if (ConfigIsExisting("itemBehaviour"))
5850 m_ItemBehaviour = ConfigGetInt("itemBehaviour");
5851
5852 //RegisterNetSyncVariableInt("m_VariablesMask");
5853 if (HasQuantity()) RegisterNetSyncVariableFloat("m_VarQuantity", GetQuantityMin(), m_VarQuantityMax);
5854 RegisterNetSyncVariableFloat("m_VarWet", GetWetMin(), GetWetMax(), 2);
5855 RegisterNetSyncVariableInt("m_VarLiquidType");
5856 RegisterNetSyncVariableInt("m_Cleanness",0,1);
5857
5858 RegisterNetSyncVariableBoolSignal("m_WantPlayImpactSound");
5859 RegisterNetSyncVariableFloat("m_ImpactSpeed");
5860 RegisterNetSyncVariableInt("m_ImpactSoundSurfaceHash");
5861
5862 RegisterNetSyncVariableInt("m_ColorComponentR", 0, 255);
5863 RegisterNetSyncVariableInt("m_ColorComponentG", 0, 255);
5864 RegisterNetSyncVariableInt("m_ColorComponentB", 0, 255);
5865 RegisterNetSyncVariableInt("m_ColorComponentA", 0, 255);
5866
5867 RegisterNetSyncVariableBool("m_IsBeingPlaced");
5868 RegisterNetSyncVariableBool("m_IsTakeable");
5869 RegisterNetSyncVariableBool("m_IsHologram");
5870
5873 {
5874 RegisterNetSyncVariableInt("m_SoundSyncPlay", 0, ITEM_SOUNDS_MAX);
5875 RegisterNetSyncVariableInt("m_SoundSyncStop", 0, ITEM_SOUNDS_MAX);
5876 RegisterNetSyncVariableInt("m_SoundSyncSlotID", int.MIN, int.MAX);
5877 }
5878
5879 m_LockSoundSet = ConfigGetString("lockSoundSet");
5880
5882 if (ConfigIsExisting("temperaturePerQuantityWeight"))
5883 m_TemperaturePerQuantityWeight = ConfigGetFloat("temperaturePerQuantityWeight");
5884
5885 m_SoundSyncSlotID = -1;
5886 }
5887
5888 override int GetQuickBarBonus()
5889 {
5890 return m_QuickBarBonus;
5891 }
5892
5893 void InitializeActions()
5894 {
5896 if (!m_InputActionMap)
5897 {
5899 m_InputActionMap = iam;
5900 SetActions();
5902 }
5903 }
5904
5905 override void GetActions(typename action_input_type, out array<ActionBase_Basic> actions)
5906 {
5908 {
5909 m_ActionsInitialize = true;
5911 }
5912
5913 actions = m_InputActionMap.Get(action_input_type);
5914 }
5915
5916 void SetActions()
5917 {
5918 AddAction(ActionTakeItem);
5919 AddAction(ActionTakeItemToHands);
5920 AddAction(ActionWorldCraft);
5922 AddAction(ActionAttachWithSwitch);
5923 }
5924
5925 void SetActionAnimOverrides(); // Override action animation for specific item
5926
5927 void AddAction(typename actionName)
5928 {
5929 ActionBase action = ActionManagerBase.GetAction(actionName);
5930
5931 if (!action)
5932 {
5933 Debug.LogError("Action " + actionName + " dosn't exist!");
5934 return;
5935 }
5936
5937 typename ai = action.GetInputType();
5938 if (!ai)
5939 {
5940 m_ActionsInitialize = false;
5941 return;
5942 }
5943
5944 array<ActionBase_Basic> action_array = m_InputActionMap.Get(ai);
5945 if (!action_array)
5946 {
5947 action_array = new array<ActionBase_Basic>;
5948 m_InputActionMap.Insert(ai, action_array);
5949 }
5950 if (LogManager.IsActionLogEnable())
5951 {
5952 Debug.ActionLog(action.ToString() + " -> " + ai, this.ToString() , "n/a", "Add action");
5953 }
5954
5955 if (action_array.Find(action) != -1)
5956 {
5957 Debug.Log("Action " + action.Type() + " already added to " + this + ", skipping!");
5958 }
5959 else
5960 {
5961 action_array.Insert(action);
5962 }
5963 }
5964
5965 void RemoveAction(typename actionName)
5966 {
5967 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
5968 ActionBase action = player.GetActionManager().GetAction(actionName);
5969 typename ai = action.GetInputType();
5970 array<ActionBase_Basic> action_array = m_InputActionMap.Get(ai);
5971
5972 if (action_array)
5973 {
5974 action_array.RemoveItem(action);
5975 }
5976 }
5977
5978 // Allows override of default action command per item, defined in the SetActionAnimOverrides() of the item's class
5979 // Set -1 for params which should stay in default state
5980 void OverrideActionAnimation(typename action, int commandUID, int stanceMask = -1, int commandUIDProne = -1)
5981 {
5982 ActionOverrideData overrideData = new ActionOverrideData();
5983 overrideData.m_CommandUID = commandUID;
5984 overrideData.m_CommandUIDProne = commandUIDProne;
5985 overrideData.m_StanceMask = stanceMask;
5986
5987 TActionAnimOverrideMap actionMap = m_ItemActionOverrides.Get(action);
5988 if (!actionMap) // create new map of action > overidables map
5989 {
5990 actionMap = new TActionAnimOverrideMap();
5991 m_ItemActionOverrides.Insert(action, actionMap);
5992 }
5993
5994 actionMap.Insert(this.Type(), overrideData); // insert item -> overrides
5995
5996 }
5997
5998 void OnItemInHandsPlayerSwimStart(PlayerBase player);
5999
6000 ScriptedLightBase GetLight();
6001
6002 // Loads muzzle flash particle configuration from config and saves it to a map for faster access
6003 void LoadParticleConfigOnFire(int id)
6004 {
6005 if (!m_OnFireEffect)
6007
6010
6011 string config_to_search = "CfgVehicles";
6012 string muzzle_owner_config;
6013
6014 if (!m_OnFireEffect.Contains(id))
6015 {
6016 if (IsInherited(Weapon))
6017 config_to_search = "CfgWeapons";
6018
6019 muzzle_owner_config = config_to_search + " " + GetType() + " ";
6020
6021 string config_OnFire_class = muzzle_owner_config + "Particles " + "OnFire ";
6022
6023 int config_OnFire_subclass_count = g_Game.ConfigGetChildrenCount(config_OnFire_class);
6024
6025 if (config_OnFire_subclass_count > 0)
6026 {
6027 array<ref WeaponParticlesOnFire> WPOF_array = new array<ref WeaponParticlesOnFire>;
6028
6029 for (int i = 0; i < config_OnFire_subclass_count; i++)
6030 {
6031 string particle_class = "";
6032 g_Game.ConfigGetChildName(config_OnFire_class, i, particle_class);
6033 string config_OnFire_entry = config_OnFire_class + particle_class;
6034 WeaponParticlesOnFire WPOF = new WeaponParticlesOnFire(this, config_OnFire_entry);
6035 WPOF_array.Insert(WPOF);
6036 }
6037
6038
6039 m_OnFireEffect.Insert(id, WPOF_array);
6040 }
6041 }
6042
6043 if (!m_OnBulletCasingEjectEffect.Contains(id))
6044 {
6045 config_to_search = "CfgWeapons"; // Bullet Eject efect is supported on weapons only.
6046 muzzle_owner_config = config_to_search + " " + GetType() + " ";
6047
6048 string config_OnBulletCasingEject_class = muzzle_owner_config + "Particles " + "OnBulletCasingEject ";
6049
6050 int config_OnBulletCasingEject_count = g_Game.ConfigGetChildrenCount(config_OnBulletCasingEject_class);
6051
6052 if (config_OnBulletCasingEject_count > 0 && IsInherited(Weapon))
6053 {
6054 array<ref WeaponParticlesOnBulletCasingEject> WPOBE_array = new array<ref WeaponParticlesOnBulletCasingEject>;
6055
6056 for (i = 0; i < config_OnBulletCasingEject_count; i++)
6057 {
6058 string particle_class2 = "";
6059 g_Game.ConfigGetChildName(config_OnBulletCasingEject_class, i, particle_class2);
6060 string config_OnBulletCasingEject_entry = config_OnBulletCasingEject_class + particle_class2;
6061 WeaponParticlesOnBulletCasingEject WPOBE = new WeaponParticlesOnBulletCasingEject(this, config_OnBulletCasingEject_entry);
6062 WPOBE_array.Insert(WPOBE);
6063 }
6064
6065
6066 m_OnBulletCasingEjectEffect.Insert(id, WPOBE_array);
6067 }
6068 }
6069 }
6070
6071 // Loads muzzle flash particle configuration from config and saves it to a map for faster access
6073 {
6076
6077 if (!m_OnOverheatingEffect.Contains(id))
6078 {
6079 string config_to_search = "CfgVehicles";
6080
6081 if (IsInherited(Weapon))
6082 config_to_search = "CfgWeapons";
6083
6084 string muzzle_owner_config = config_to_search + " " + GetType() + " ";
6085 string config_OnOverheating_class = muzzle_owner_config + "Particles " + "OnOverheating ";
6086
6087 if (g_Game.ConfigIsExisting(config_OnOverheating_class))
6088 {
6089
6090 m_ShotsToStartOverheating = g_Game.ConfigGetFloat(config_OnOverheating_class + "shotsToStartOverheating");
6091
6093 {
6094 m_ShotsToStartOverheating = -1; // This prevents futher readings from config for future creations of this item
6095 string error = "Error reading config " + GetType() + ">Particles>OnOverheating - Parameter shotsToStartOverheating is configured wrong or is missing! Its value must be 1 or higher!";
6096 Error(error);
6097 return;
6098 }
6099
6100 m_OverheatingDecayInterval = g_Game.ConfigGetFloat(config_OnOverheating_class + "overheatingDecayInterval");
6101 m_MaxOverheatingValue = g_Game.ConfigGetFloat(config_OnOverheating_class + "maxOverheatingValue");
6102
6103
6104
6105 int config_OnOverheating_subclass_count = g_Game.ConfigGetChildrenCount(config_OnOverheating_class);
6106 array<ref WeaponParticlesOnOverheating> WPOOH_array = new array<ref WeaponParticlesOnOverheating>;
6107
6108 for (int i = 0; i < config_OnOverheating_subclass_count; i++)
6109 {
6110 string particle_class = "";
6111 g_Game.ConfigGetChildName(config_OnOverheating_class, i, particle_class);
6112 string config_OnOverheating_entry = config_OnOverheating_class + particle_class;
6113 int entry_type = g_Game.ConfigGetType(config_OnOverheating_entry);
6114
6115 if (entry_type == CT_CLASS)
6116 {
6117 WeaponParticlesOnOverheating WPOF = new WeaponParticlesOnOverheating(this, config_OnOverheating_entry);
6118 WPOOH_array.Insert(WPOF);
6119 }
6120 }
6121
6122
6123 m_OnOverheatingEffect.Insert(id, WPOOH_array);
6124 }
6125 }
6126 }
6127
6128 float GetOverheatingValue()
6129 {
6130 return m_OverheatingShots;
6131 }
6132
6133 void IncreaseOverheating(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
6134 {
6135 if (m_MaxOverheatingValue > 0)
6136 {
6138
6139 if (!m_CheckOverheating)
6141
6143 m_CheckOverheating.Run(m_OverheatingDecayInterval, this, "OnOverheatingDecay");
6144
6145 CheckOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
6146 }
6147 }
6148
6149 void CheckOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
6150 {
6152 UpdateOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
6153
6155 StartOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
6156
6158 StopOverheating(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
6159
6161 {
6163 }
6164 }
6165
6167 {
6169 }
6170
6171 void OnOverheatingDecay()
6172 {
6173 if (m_MaxOverheatingValue > 0)
6174 m_OverheatingShots -= 1 + m_OverheatingShots / m_MaxOverheatingValue; // The hotter a barrel is, the faster it needs to cool down.
6175 else
6177
6178 if (m_OverheatingShots <= 0)
6179 {
6182 }
6183 else
6184 {
6185 if (!m_CheckOverheating)
6187
6189 m_CheckOverheating.Run(m_OverheatingDecayInterval, this, "OnOverheatingDecay");
6190 }
6191
6192 CheckOverheating(this, "", this);
6193 }
6194
6195 void StartOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
6196 {
6198 ItemBase.PlayOverheatingParticles(this, ammoType, this, suppressor, "CfgWeapons");
6199 }
6200
6201 void UpdateOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
6202 {
6204 ItemBase.UpdateOverheatingParticles(this, ammoType, this, suppressor, "CfgWeapons");
6206 }
6207
6208 void StopOverheating(ItemBase weapon = null, string ammoType = "", ItemBase muzzle_owner = null, ItemBase suppressor = null, string config_to_search = "")
6209 {
6211 ItemBase.StopOverheatingParticles(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
6212 }
6213
6214 void RegisterOverheatingParticle(Particle p, float min_heat_coef, float max_heat_coef, int particle_id, Object parent, vector local_pos, vector local_ori)
6215 {
6217 m_OverheatingParticles = new array<ref OverheatingParticle>;
6218
6219 OverheatingParticle OP = new OverheatingParticle();
6220 OP.RegisterParticle(p);
6221 OP.SetOverheatingLimitMin(min_heat_coef);
6222 OP.SetOverheatingLimitMax(max_heat_coef);
6223 OP.SetParticleParams(particle_id, parent, local_pos, local_ori);
6224
6225 m_OverheatingParticles.Insert(OP);
6226 }
6227
6228 float GetOverheatingCoef()
6229 {
6230 if (m_MaxOverheatingValue > 0)
6232
6233 return -1;
6234 }
6235
6237 {
6239 {
6240 float overheat_coef = GetOverheatingCoef();
6241 int count = m_OverheatingParticles.Count();
6242
6243 for (int i = count; i > 0; --i)
6244 {
6245 int id = i - 1;
6246 OverheatingParticle OP = m_OverheatingParticles.Get(id);
6247 Particle p = OP.GetParticle();
6248
6249 float overheat_min = OP.GetOverheatingLimitMin();
6250 float overheat_max = OP.GetOverheatingLimitMax();
6251
6252 if (overheat_coef < overheat_min && overheat_coef >= overheat_max)
6253 {
6254 if (p)
6255 {
6256 p.Stop();
6257 OP.RegisterParticle(null);
6258 }
6259 }
6260 }
6261 }
6262 }
6263
6265 {
6267 {
6268 for (int i = m_OverheatingParticles.Count(); i > 0; i--)
6269 {
6270 int id = i - 1;
6271 OverheatingParticle OP = m_OverheatingParticles.Get(id);
6272
6273 if (OP)
6274 {
6275 Particle p = OP.GetParticle();
6276
6277 if (p)
6278 {
6279 p.Stop();
6280 }
6281
6282 delete OP;
6283 }
6284 }
6285
6286 m_OverheatingParticles.Clear();
6288 }
6289 }
6290
6292 float GetInfectionChance(int system = 0, Param param = null)
6293 {
6294 return 0.0;
6295 }
6296
6297
6298 float GetDisinfectQuantity(int system = 0, Param param1 = null)
6299 {
6300 return 250;//default value
6301 }
6302
6303 float GetFilterDamageRatio()
6304 {
6305 return 0;
6306 }
6307
6309 bool HasMuzzle()
6310 {
6311 if (IsInherited(Weapon) || IsInherited(SuppressorBase))
6312 return true;
6313
6314 return false;
6315 }
6316
6318 int GetMuzzleID()
6319 {
6320 if (!m_WeaponTypeToID)
6321 m_WeaponTypeToID = new map<string, int>;
6322
6323 if (m_WeaponTypeToID.Contains(GetType()))
6324 {
6325 return m_WeaponTypeToID.Get(GetType());
6326 }
6327 else
6328 {
6329 // Register new weapon ID
6331 }
6332
6334 }
6335
6342 {
6343 return -1;
6344 }
6345
6346
6347
6348 // -------------------------------------------------------------------------
6349 void ~ItemBase()
6350 {
6351 if (g_Game && g_Game.GetPlayer() && (!g_Game.IsDedicatedServer()))
6352 {
6353 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
6354 int r_index = player.GetHumanInventory().FindUserReservedLocationIndex(this);
6355
6356 if (r_index >= 0)
6357 {
6358 InventoryLocation r_il = new InventoryLocation;
6359 player.GetHumanInventory().GetUserReservedLocation(r_index,r_il);
6360
6361 player.GetHumanInventory().ClearUserReservedLocationAtIndex(r_index);
6362 int r_type = r_il.GetType();
6363 if (r_type == InventoryLocationType.CARGO || r_type == InventoryLocationType.PROXYCARGO)
6364 {
6365 r_il.GetParent().GetOnReleaseLock().Invoke(this);
6366 }
6367 else if (r_type == InventoryLocationType.ATTACHMENT)
6368 {
6369 r_il.GetParent().GetOnAttachmentReleaseLock().Invoke(this, r_il.GetSlot());
6370 }
6371
6372 }
6373
6374 player.GetHumanInventory().ClearUserReservedLocation(this);
6375 }
6376
6377 if (m_LockingSound)
6378 SEffectManager.DestroyEffect(m_LockingSound);
6379 }
6380
6381
6382
6383 // -------------------------------------------------------------------------
6384 static int GetDebugActionsMask()
6385 {
6386 return ItemBase.m_DebugActionsMask;
6387 }
6388
6389 static bool HasDebugActionsMask(int mask)
6390 {
6391 return ItemBase.m_DebugActionsMask & mask;
6392 }
6393
6394 static void SetDebugActionsMask(int mask)
6395 {
6396 ItemBase.m_DebugActionsMask = mask;
6397 }
6398
6399 static void AddDebugActionsMask(int mask)
6400 {
6401 ItemBase.m_DebugActionsMask |= mask;
6402 }
6403
6404 static void RemoveDebugActionsMask(int mask)
6405 {
6406 ItemBase.m_DebugActionsMask &= ~mask;
6407 }
6408
6409 static void ToggleDebugActionsMask(int mask)
6410 {
6411 if (HasDebugActionsMask(mask))
6412 {
6414 }
6415 else
6416 {
6417 AddDebugActionsMask(mask);
6418 }
6419 }
6420
6421 // -------------------------------------------------------------------------
6422 void SetCEBasedQuantity()
6423 {
6424 if (GetEconomyProfile())
6425 {
6426 float q_max = GetEconomyProfile().GetQuantityMax();
6427 if (q_max > 0)
6428 {
6429 float q_min = GetEconomyProfile().GetQuantityMin();
6430 float quantity_randomized = Math.RandomFloatInclusive(q_min, q_max);
6431
6432 if (HasComponent(COMP_TYPE_ENERGY_MANAGER))//more direct access for speed
6433 {
6434 ComponentEnergyManager comp = GetCompEM();
6435 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
6436 {
6437 comp.SetEnergy0To1(quantity_randomized);
6438 }
6439 }
6440 else if (HasQuantity())
6441 {
6442 SetQuantityNormalized(quantity_randomized, false);
6443 //PrintString("<==> Normalized quantity for item: "+ GetType()+", qmin:"+q_min.ToString()+"; qmax:"+q_max.ToString()+";quantity:" +quantity_randomized.ToString());
6444 }
6445
6446 }
6447 }
6448 }
6449
6451 void LockToParent()
6452 {
6453 EntityAI parent = GetHierarchyParent();
6454
6455 if (parent)
6456 {
6457 InventoryLocation inventory_location_to_lock = new InventoryLocation;
6458 GetInventory().GetCurrentInventoryLocation(inventory_location_to_lock);
6459 parent.GetInventory().SetSlotLock(inventory_location_to_lock.GetSlot(), true);
6460 }
6461 }
6462
6464 void UnlockFromParent()
6465 {
6466 EntityAI parent = GetHierarchyParent();
6467
6468 if (parent)
6469 {
6470 InventoryLocation inventory_location_to_unlock = new InventoryLocation;
6471 GetInventory().GetCurrentInventoryLocation(inventory_location_to_unlock);
6472 parent.GetInventory().SetSlotLock(inventory_location_to_unlock.GetSlot(), false);
6473 }
6474 }
6475
6476 override void CombineItemsClient(EntityAI entity2, bool use_stack_max = true)
6477 {
6478 /*
6479 ref Param1<EntityAI> item = new Param1<EntityAI>(entity2);
6480 RPCSingleParam(ERPCs.RPC_ITEM_COMBINE, item, g_Game.GetPlayer());
6481 */
6482 ItemBase item2 = ItemBase.Cast(entity2);
6483
6484 if (g_Game.IsClient())
6485 {
6486 if (ScriptInputUserData.CanStoreInputUserData())
6487 {
6488 ScriptInputUserData ctx = new ScriptInputUserData;
6490 ctx.Write(-1);
6491 ItemBase i1 = this; // @NOTE: workaround for correct serialization
6492 ctx.Write(i1);
6493 ctx.Write(item2);
6494 ctx.Write(use_stack_max);
6495 ctx.Write(-1);
6496 ctx.Send();
6497
6498 if (IsCombineAll(item2, use_stack_max))
6499 {
6500 g_Game.GetPlayer().GetInventory().AddInventoryReservationEx(item2,null,GameInventory.c_InventoryReservationTimeoutShortMS);
6501 }
6502 }
6503 }
6504 else if (!g_Game.IsMultiplayer())
6505 {
6506 CombineItems(item2, use_stack_max);
6507 }
6508 }
6509
6510 bool IsLiquidPresent()
6511 {
6512 return (GetLiquidType() != 0 && HasQuantity());
6513 }
6514
6515 bool IsLiquidContainer()
6516 {
6517 return m_LiquidContainerMask != 0;
6518 }
6519
6521 {
6522 return m_LiquidContainerMask;
6523 }
6524
6525 bool IsBloodContainer()
6526 {
6527 //m_LiquidContainerMask & GROUP_LIQUID_BLOOD ???
6528 return false;
6529 }
6530
6531 bool IsNVG()
6532 {
6533 return false;
6534 }
6535
6538 bool IsExplosive()
6539 {
6540 return false;
6541 }
6542
6544 {
6545 return "";
6546 }
6547
6549
6550 bool IsLightSource()
6551 {
6552 return false;
6553 }
6554
6556 {
6557 return true;
6558 }
6559
6560 //--- ACTION CONDITIONS
6561 //direction
6562 bool IsFacingPlayer(PlayerBase player, string selection)
6563 {
6564 return true;
6565 }
6566
6567 bool IsPlayerInside(PlayerBase player, string selection)
6568 {
6569 return true;
6570 }
6571
6572 override bool CanObstruct()
6573 {
6574 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
6575 return !player || !IsPlayerInside(player, "");
6576 }
6577
6578 override bool IsBeingPlaced()
6579 {
6580 return m_IsBeingPlaced;
6581 }
6582
6583 void SetIsBeingPlaced(bool is_being_placed)
6584 {
6585 m_IsBeingPlaced = is_being_placed;
6586 if (!is_being_placed)
6588 SetSynchDirty();
6589 }
6590
6591 //server-side
6592 void OnEndPlacement() {}
6593
6594 override bool IsHologram()
6595 {
6596 return m_IsHologram;
6597 }
6598
6599 bool CanBeDigged()
6600 {
6601 return m_CanBeDigged;
6602 }
6603
6605 {
6606 return 1;
6607 }
6608
6609 bool CanMakeGardenplot()
6610 {
6611 return false;
6612 }
6613
6614 void SetIsHologram(bool is_hologram)
6615 {
6616 m_IsHologram = is_hologram;
6617 SetSynchDirty();
6618 }
6619 /*
6620 protected float GetNutritionalEnergy()
6621 {
6622 Edible_Base edible = Edible_Base.Cast(this);
6623 return edible.GetFoodEnergy();
6624 }
6625
6626 protected float GetNutritionalWaterContent()
6627 {
6628 Edible_Base edible = Edible_Base.Cast(this);
6629 return edible.GetFoodWater();
6630 }
6631
6632 protected float GetNutritionalIndex()
6633 {
6634 Edible_Base edible = Edible_Base.Cast(this);
6635 return edible.GetFoodNutritionalIndex();
6636 }
6637
6638 protected float GetNutritionalFullnessIndex()
6639 {
6640 Edible_Base edible = Edible_Base.Cast(this);
6641 return edible.GetFoodTotalVolume();
6642 }
6643
6644 protected float GetNutritionalToxicity()
6645 {
6646 Edible_Base edible = Edible_Base.Cast(this);
6647 return edible.GetFoodToxicity();
6648
6649 }
6650 */
6651
6652
6653 // -------------------------------------------------------------------------
6654 override void OnMovedInsideCargo(EntityAI container)
6655 {
6656 super.OnMovedInsideCargo(container);
6657
6658 MiscGameplayFunctions.RemoveAllAttachedChildrenByTypename(this, {Bolt_Base});
6659 }
6660
6661 override void EEItemLocationChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
6662 {
6663 super.EEItemLocationChanged(oldLoc, newLoc);
6664
6665 PlayerBase newPlayer = null;
6666 PlayerBase oldPlayer = null;
6667
6668 if (newLoc.GetParent())
6669 newPlayer = PlayerBase.Cast(newLoc.GetParent().GetHierarchyRootPlayer());
6670
6671 if (oldLoc.GetParent())
6672 oldPlayer = PlayerBase.Cast(oldLoc.GetParent().GetHierarchyRootPlayer());
6673
6674 if (oldPlayer && oldLoc.GetType() == InventoryLocationType.HANDS)
6675 {
6676 int rIndex = oldPlayer.GetHumanInventory().FindUserReservedLocationIndex(this);
6677
6678 if (rIndex >= 0)
6679 {
6680 InventoryLocation rIl = new InventoryLocation;
6681 oldPlayer.GetHumanInventory().GetUserReservedLocation(rIndex, rIl);
6682
6683 oldPlayer.GetHumanInventory().ClearUserReservedLocationAtIndex(rIndex);
6684 int rType = rIl.GetType();
6685 if (rType == InventoryLocationType.CARGO || rType == InventoryLocationType.PROXYCARGO)
6686 {
6687 rIl.GetParent().GetOnReleaseLock().Invoke(this);
6688 }
6689 else if (rType == InventoryLocationType.ATTACHMENT)
6690 {
6691 rIl.GetParent().GetOnAttachmentReleaseLock().Invoke(this, rIl.GetSlot());
6692 }
6693
6694 }
6695 }
6696
6697 if (newLoc.GetType() == InventoryLocationType.HANDS && oldLoc.GetType() != InventoryLocationType.TEMP)
6698 {
6699 if (newPlayer)
6700 newPlayer.ForceStandUpForHeavyItems(newLoc.GetItem());
6701
6702 if (newPlayer == oldPlayer)
6703 {
6704 if (oldLoc.GetParent() && newPlayer.GetHumanInventory().LocationGetEntity(oldLoc) == NULL)
6705 {
6706 if (oldLoc.GetType() == InventoryLocationType.CARGO)
6707 {
6708 if (oldLoc.GetParent().GetInventory().TestAddEntityInCargoExLoc(oldLoc, false, false, false, true, false, false))
6709 {
6710 newPlayer.GetHumanInventory().SetUserReservedLocation(this,oldLoc);
6711 }
6712 }
6713 else
6714 {
6715 newPlayer.GetHumanInventory().SetUserReservedLocation(this,oldLoc);
6716 }
6717 }
6718
6719 if (newPlayer.GetHumanInventory().FindUserReservedLocationIndex(this) >= 0)
6720 {
6721 int type = oldLoc.GetType();
6722 if (type == InventoryLocationType.CARGO || type == InventoryLocationType.PROXYCARGO)
6723 {
6724 oldLoc.GetParent().GetOnSetLock().Invoke(this);
6725 }
6726 else if (type == InventoryLocationType.ATTACHMENT)
6727 {
6728 oldLoc.GetParent().GetOnAttachmentSetLock().Invoke(this, oldLoc.GetSlot());
6729 }
6730 }
6731 if (!m_OldLocation)
6732 {
6733 m_OldLocation = new InventoryLocation;
6734 }
6735 m_OldLocation.Copy(oldLoc);
6736 }
6737 else
6738 {
6739 if (m_OldLocation)
6740 {
6741 m_OldLocation.Reset();
6742 }
6743 }
6744
6745 g_Game.GetAnalyticsClient().OnItemAttachedAtPlayer(this,"Hands");
6746 }
6747 else
6748 {
6749 if (newPlayer)
6750 {
6751 int resIndex = newPlayer.GetHumanInventory().FindCollidingUserReservedLocationIndex(this, newLoc);
6752 if (resIndex >= 0)
6753 {
6754 InventoryLocation il = new InventoryLocation;
6755 newPlayer.GetHumanInventory().GetUserReservedLocation(resIndex, il);
6756 ItemBase it = ItemBase.Cast(il.GetItem());
6757 newPlayer.GetHumanInventory().ClearUserReservedLocationAtIndex(resIndex);
6758 int rel_type = il.GetType();
6759 if (rel_type == InventoryLocationType.CARGO || rel_type == InventoryLocationType.PROXYCARGO)
6760 {
6761 il.GetParent().GetOnReleaseLock().Invoke(it);
6762 }
6763 else if (rel_type == InventoryLocationType.ATTACHMENT)
6764 {
6765 il.GetParent().GetOnAttachmentReleaseLock().Invoke(it, il.GetSlot());
6766 }
6767 //it.GetOnReleaseLock().Invoke(it);
6768 }
6769 }
6770 else if (oldPlayer && newLoc.GetType() == InventoryLocationType.GROUND && m_ThrowItemOnDrop)
6771 {
6772 //ThrowPhysically(oldPlayer, vector.Zero);
6773 m_ThrowItemOnDrop = false;
6774 }
6775
6776 if (m_OldLocation)
6777 {
6778 m_OldLocation.Reset();
6779 }
6780 }
6781
6782 if (oldLoc.GetType() == InventoryLocationType.TEMP)
6783 {
6784 PluginInventoryRepair.Cast(GetPlugin(PluginInventoryRepair)).Remove(oldLoc.GetItem());
6785 }
6786
6787 if (newLoc.GetType() == InventoryLocationType.TEMP)
6788 {
6789 PluginInventoryRepair.Cast(GetPlugin(PluginInventoryRepair)).Add(oldLoc.GetItem());
6790 }
6791 }
6792
6793 override void EOnContact(IEntity other, Contact extra)
6794 {
6796 {
6797 int liquidType = -1;
6798 float impactSpeed = ProcessImpactSoundEx(other, extra, m_ConfigWeight, m_ImpactSoundSurfaceHash, liquidType);
6799 if (impactSpeed > 0.0)
6800 {
6801 m_ImpactSpeed = impactSpeed;
6802 #ifndef SERVER
6803 PlayImpactSound(m_ConfigWeight, m_ImpactSpeed, m_ImpactSoundSurfaceHash);
6804 #else
6805 m_WantPlayImpactSound = true;
6806 SetSynchDirty();
6807 #endif
6808 m_CanPlayImpactSound = (liquidType == -1);// prevents further playing of the sound when the surface is a liquid type
6809 }
6810 }
6811
6812 #ifdef SERVER
6813 if (GetCompEM() && GetCompEM().IsPlugged())
6814 {
6815 if (GetCompEM().GetCordLength() < vector.Distance(GetPosition(), GetCompEM().GetEnergySource().GetPosition()))
6816 GetCompEM().UnplugThis();
6817 }
6818 #endif
6819 }
6820
6821 void RefreshPhysics();
6822
6823 override void OnCreatePhysics()
6824 {
6826 }
6827
6828 override void OnItemAttachmentSlotChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
6829 {
6830
6831 }
6832 // -------------------------------------------------------------------------
6833 override void OnItemLocationChanged(EntityAI old_owner, EntityAI new_owner)
6834 {
6835 super.OnItemLocationChanged(old_owner, new_owner);
6836
6837 PlayerBase relatedPlayer = PlayerBase.Cast(old_owner);
6838 PlayerBase playerNew = PlayerBase.Cast(new_owner);
6839
6840 if (!relatedPlayer && playerNew)
6841 relatedPlayer = playerNew;
6842
6843 if (relatedPlayer && relatedPlayer.GetPerformedActionID() != -1)
6844 {
6845 ActionManagerBase actionMgr = relatedPlayer.GetActionManager();
6846 if (actionMgr)
6847 {
6848 ActionBase currentAction = actionMgr.GetRunningAction();
6849 if (currentAction)
6850 currentAction.OnItemLocationChanged(this);
6851 }
6852 }
6853
6854 Man ownerPlayerOld = null;
6855 Man ownerPlayerNew = null;
6856
6857 if (old_owner)
6858 {
6859 if (old_owner.IsMan())
6860 {
6861 ownerPlayerOld = Man.Cast(old_owner);
6862 }
6863 else
6864 {
6865 ownerPlayerOld = Man.Cast(old_owner.GetHierarchyRootPlayer());
6866 }
6867 }
6868 else
6869 {
6870 if (new_owner && IsElectricAppliance() && GetCompEM() && GetCompEM().IsPlugged())
6871 {
6872 ActionBase action = ActionManagerBase.GetAction(ActionRepositionPluggedItem);
6873
6874 if (!action || !playerNew || playerNew.GetPerformedActionID() != action.GetID())
6875 {
6876 GetCompEM().UnplugThis();
6877 }
6878 }
6879 }
6880
6881 if (new_owner)
6882 {
6883 if (new_owner.IsMan())
6884 {
6885 ownerPlayerNew = Man.Cast(new_owner);
6886 }
6887 else
6888 {
6889 ownerPlayerNew = Man.Cast(new_owner.GetHierarchyRootPlayer());
6890 }
6891 }
6892
6893 if (ownerPlayerOld != ownerPlayerNew)
6894 {
6895 if (ownerPlayerOld)
6896 {
6897 array<EntityAI> subItemsExit = new array<EntityAI>;
6898 GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER,subItemsExit);
6899 for (int i = 0; i < subItemsExit.Count(); i++)
6900 {
6901 ItemBase itemExit = ItemBase.Cast(subItemsExit.Get(i));
6902 itemExit.OnInventoryExit(ownerPlayerOld);
6903 }
6904 }
6905
6906 if (ownerPlayerNew)
6907 {
6908 array<EntityAI> subItemsEnter = new array<EntityAI>;
6909 GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER,subItemsEnter);
6910 for (int j = 0; j < subItemsEnter.Count(); j++)
6911 {
6912 ItemBase itemEnter = ItemBase.Cast(subItemsEnter.Get(j));
6913 itemEnter.OnInventoryEnter(ownerPlayerNew);
6914 }
6915 }
6916 }
6917 else if (ownerPlayerNew != null)
6918 {
6919 PlayerBase nplayer;
6920 if (PlayerBase.CastTo(nplayer, ownerPlayerNew))
6921 {
6922 array<EntityAI> subItemsUpdate = new array<EntityAI>;
6923 GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER,subItemsUpdate);
6924 for (int k = 0; k < subItemsUpdate.Count(); k++)
6925 {
6926 ItemBase itemUpdate = ItemBase.Cast(subItemsUpdate.Get(k));
6927 itemUpdate.UpdateQuickbarShortcutVisibility(nplayer);
6928 }
6929 }
6930 }
6931
6932 if (old_owner)
6933 old_owner.OnChildItemRemoved(this);
6934 if (new_owner)
6935 new_owner.OnChildItemReceived(this);
6936 }
6937
6938 // -------------------------------------------------------------------------------
6939 override void EEDelete(EntityAI parent)
6940 {
6941 super.EEDelete(parent);
6942 PlayerBase player = PlayerBase.Cast(GetHierarchyRootPlayer());
6943 if (player)
6944 {
6945 OnInventoryExit(player);
6946
6947 if (player.IsAlive())
6948 {
6949 int r_index = player.GetHumanInventory().FindUserReservedLocationIndex(this);
6950 if (r_index >= 0)
6951 {
6952 InventoryLocation r_il = new InventoryLocation;
6953 player.GetHumanInventory().GetUserReservedLocation(r_index,r_il);
6954
6955 player.GetHumanInventory().ClearUserReservedLocationAtIndex(r_index);
6956 int r_type = r_il.GetType();
6957 if (r_type == InventoryLocationType.CARGO || r_type == InventoryLocationType.PROXYCARGO)
6958 {
6959 r_il.GetParent().GetOnReleaseLock().Invoke(this);
6960 }
6961 else if (r_type == InventoryLocationType.ATTACHMENT)
6962 {
6963 r_il.GetParent().GetOnAttachmentReleaseLock().Invoke(this, r_il.GetSlot());
6964 }
6965
6966 }
6967
6968 player.RemoveQuickBarEntityShortcut(this);
6969 }
6970 }
6971 }
6972 // -------------------------------------------------------------------------------
6973 override void EEKilled(Object killer)
6974 {
6975 super.EEKilled(killer);
6976
6978 if (killer && killer.IsFireplace() && CanExplodeInFire())
6979 {
6980 if (GetTemperature() >= GameConstants.ITEM_TEMPERATURE_TO_EXPLODE_MIN)
6981 {
6982 if (IsMagazine())
6983 {
6984 if (Magazine.Cast(this).GetAmmoCount() > 0)
6985 {
6986 ExplodeAmmo();
6987 }
6988 }
6989 else
6990 {
6991 Explode(DamageType.EXPLOSION);
6992 }
6993 }
6994 }
6995 }
6996
6997 override void OnWasAttached(EntityAI parent, int slot_id)
6998 {
6999 MiscGameplayFunctions.RemoveAllAttachedChildrenByTypename(this, {Bolt_Base});
7000
7001 super.OnWasAttached(parent, slot_id);
7002
7003 if (HasQuantity())
7004 UpdateNetSyncVariableFloat("m_VarQuantity", GetQuantityMin(), m_VarQuantityMax);
7005
7006 if (g_Game.IsServer() || !g_Game.IsMultiplayer()) // single player or server side multiplayer
7007 StartItemSoundServer(SoundConstants.ITEM_ATTACH, slot_id);
7008 }
7009
7010 override void OnWasDetached(EntityAI parent, int slot_id)
7011 {
7012 super.OnWasDetached(parent, slot_id);
7013
7014 if (HasQuantity())
7015 UpdateNetSyncVariableFloat("m_VarQuantity", GetQuantityMin(), m_VarQuantityMax);
7016
7017 if (g_Game.IsServer() || !g_Game.IsMultiplayer()) // single player or server side multiplayer
7018 StartItemSoundServer(SoundConstants.ITEM_DETACH, slot_id);
7019 }
7020
7021 override string ChangeIntoOnAttach(string slot)
7022 {
7023 int idx;
7024 TStringArray inventory_slots = new TStringArray;
7025 TStringArray attach_types = new TStringArray;
7026
7027 ConfigGetTextArray("ChangeInventorySlot",inventory_slots);
7028 if (inventory_slots.Count() < 1) //is string
7029 {
7030 inventory_slots.Insert(ConfigGetString("ChangeInventorySlot"));
7031 attach_types.Insert(ConfigGetString("ChangeIntoOnAttach"));
7032 }
7033 else //is array
7034 {
7035 ConfigGetTextArray("ChangeIntoOnAttach",attach_types);
7036 }
7037
7038 idx = inventory_slots.Find(slot);
7039 if (idx < 0)
7040 return "";
7041
7042 return attach_types.Get(idx);
7043 }
7044
7045 override string ChangeIntoOnDetach()
7046 {
7047 int idx = -1;
7048 string slot;
7049
7050 TStringArray inventory_slots = new TStringArray;
7051 TStringArray detach_types = new TStringArray;
7052
7053 this.ConfigGetTextArray("ChangeInventorySlot",inventory_slots);
7054 if (inventory_slots.Count() < 1) //is string
7055 {
7056 inventory_slots.Insert(this.ConfigGetString("ChangeInventorySlot"));
7057 detach_types.Insert(this.ConfigGetString("ChangeIntoOnDetach"));
7058 }
7059 else //is array
7060 {
7061 this.ConfigGetTextArray("ChangeIntoOnDetach",detach_types);
7062 if (detach_types.Count() < 1)
7063 detach_types.Insert(this.ConfigGetString("ChangeIntoOnDetach"));
7064 }
7065
7066 for (int i = 0; i < inventory_slots.Count(); i++)
7067 {
7068 slot = inventory_slots.Get(i);
7069 }
7070
7071 if (slot != "")
7072 {
7073 if (detach_types.Count() == 1)
7074 idx = 0;
7075 else
7076 idx = inventory_slots.Find(slot);
7077 }
7078 if (idx < 0)
7079 return "";
7080
7081 return detach_types.Get(idx);
7082 }
7083
7084 void ExplodeAmmo()
7085 {
7086 //timer
7087 ref Timer explode_timer = new Timer(CALL_CATEGORY_SYSTEM);
7088
7089 //min/max time
7090 float min_time = 1;
7091 float max_time = 3;
7092 float delay = Math.RandomFloat(min_time, max_time);
7093
7094 explode_timer.Run(delay, this, "DoAmmoExplosion");
7095 }
7096
7097 void DoAmmoExplosion()
7098 {
7099 Magazine magazine = Magazine.Cast(this);
7100 int pop_sounds_count = 6;
7101 string pop_sounds[ 6 ] = { "ammopops_1","ammopops_2","ammopops_3","ammopops_4","ammopops_5","ammopops_6" };
7102
7103 //play sound
7104 int sound_idx = Math.RandomInt(0, pop_sounds_count - 1);
7105 string sound_name = pop_sounds[ sound_idx ];
7106 g_Game.CreateSoundOnObject(this, sound_name, 20, false);
7107
7108 //remove ammo count
7109 magazine.ServerAddAmmoCount(-1);
7110
7111 //if condition then repeat -> ExplodeAmmo
7112 float min_temp_to_explode = 100; //min temperature for item to explode
7113
7114 if (magazine.GetAmmoCount() > 0 && GetTemperature() >= min_temp_to_explode) //TODO ? add check for parent -> fireplace
7115 {
7116 ExplodeAmmo();
7117 }
7118 }
7119
7120 // -------------------------------------------------------------------------------
7121 override void EEHitBy(TotalDamageResult damageResult, int damageType, EntityAI source, int component, string dmgZone, string ammo, vector modelPos, float speedCoef)
7122 {
7123 super.EEHitBy(damageResult, damageType, source, component, dmgZone, ammo, modelPos, speedCoef);
7124
7125 const int CHANCE_DAMAGE_CARGO = 4;
7126 const int CHANCE_DAMAGE_ATTACHMENT = 1;
7127 const int CHANCE_DAMAGE_NOTHING = 2;
7128
7129 if (IsClothing() || IsContainer() || IsItemTent())
7130 {
7131 float dmg = damageResult.GetDamage("","Health") * -0.5;
7132 int chances;
7133 int rnd;
7134
7135 if (GetInventory().GetCargo())
7136 {
7137 chances = CHANCE_DAMAGE_CARGO + CHANCE_DAMAGE_ATTACHMENT + CHANCE_DAMAGE_NOTHING;
7138 rnd = Math.RandomInt(0,chances);
7139
7140 if (rnd < CHANCE_DAMAGE_CARGO)
7141 {
7142 DamageItemInCargo(dmg);
7143 }
7144 else if (rnd < (chances - CHANCE_DAMAGE_NOTHING))
7145 {
7147 }
7148 }
7149 else
7150 {
7151 chances = CHANCE_DAMAGE_ATTACHMENT + CHANCE_DAMAGE_NOTHING;
7152 rnd = Math.RandomInt(0,chances);
7153
7154 if (rnd < CHANCE_DAMAGE_ATTACHMENT)
7155 {
7157 }
7158 }
7159 }
7160 }
7161
7162 bool DamageItemInCargo(float damage)
7163 {
7164 CargoBase cargo = GetInventory().GetCargo();
7165 if (cargo)
7166 {
7167 int item_count = cargo.GetItemCount();
7168 if (item_count > 0)
7169 {
7170 int random_pick = Math.RandomInt(0, item_count);
7171 ItemBase item = ItemBase.Cast(cargo.GetItem(random_pick));
7172 if (!item.IsExplosive())
7173 {
7174 item.AddHealth("","",damage);
7175 return true;
7176 }
7177 }
7178 }
7179 return false;
7180 }
7181
7182 bool DamageItemAttachments(float damage)
7183 {
7184 GameInventory inventory = GetInventory();
7185 int attachment_count = inventory.AttachmentCount();
7186 if (attachment_count > 0)
7187 {
7188 int random_pick = Math.RandomInt(0, attachment_count);
7189 ItemBase attachment = ItemBase.Cast(inventory.GetAttachmentFromIndex(random_pick));
7190 if (!attachment.IsExplosive())
7191 {
7192 attachment.AddHealth("","",damage);
7193 return true;
7194 }
7195 }
7196 return false;
7197 }
7198
7199 override bool IsSplitable()
7200 {
7201 return m_CanThisBeSplit;
7202 }
7203 //----------------
7204 override bool CanBeSplit()
7205 {
7206 if (IsSplitable() && (GetQuantity() > 1))
7207 return GetInventory().CanRemoveEntity();
7208
7209 return false;
7210 }
7211
7212 protected bool ShouldSplitQuantity(float quantity)
7213 {
7214 // don't call 'CanBeSplit' here, too strict and will introduce a freeze-crash when dismantling fence with a fireplace nearby
7215 if (!IsSplitable())
7216 return false;
7217
7218 // nothing to split?
7219 if (GetQuantity() <= 1)
7220 return false;
7221
7222 // check if we should re-use the item instead of creating a new copy?
7223 // implicit cast to int, if 'IsSplitable' returns true, these values are assumed ints
7224 int delta = GetQuantity() - quantity;
7225 if (delta == 0)
7226 return false;
7227
7228 // valid to split
7229 return true;
7230 }
7231
7232 override void SplitIntoStackMaxClient(EntityAI destination_entity, int slot_id )
7233 {
7234 if (g_Game.IsClient())
7235 {
7236 if (ScriptInputUserData.CanStoreInputUserData())
7237 {
7238 ScriptInputUserData ctx = new ScriptInputUserData;
7240 ctx.Write(1);
7241 ItemBase i1 = this; // @NOTE: workaround for correct serialization
7242 ctx.Write(i1);
7243 ctx.Write(destination_entity);
7244 ctx.Write(true);
7245 ctx.Write(slot_id);
7246 ctx.Send();
7247 }
7248 }
7249 else if (!g_Game.IsMultiplayer())
7250 {
7251 SplitIntoStackMax(destination_entity, slot_id, PlayerBase.Cast(g_Game.GetPlayer()));
7252 }
7253 }
7254
7255 void SplitIntoStackMax(EntityAI destination_entity, int slot_id, PlayerBase player)
7256 {
7257 float split_quantity_new;
7258 ItemBase new_item;
7259 float quantity = GetQuantity();
7260 float stack_max = GetTargetQuantityMax(slot_id);
7261 InventoryLocation loc = new InventoryLocation;
7262
7263 if (destination_entity && slot_id != -1 && InventorySlots.IsSlotIdValid(slot_id))
7264 {
7265 if (stack_max <= GetQuantity())
7266 split_quantity_new = stack_max;
7267 else
7268 split_quantity_new = GetQuantity();
7269
7270 if (ShouldSplitQuantity(split_quantity_new))
7271 {
7272 new_item = ItemBase.Cast(destination_entity.GetInventory().CreateAttachmentEx(this.GetType(), slot_id));
7273 if (new_item)
7274 {
7275 new_item.SetResultOfSplit(true);
7276 MiscGameplayFunctions.TransferItemProperties(this, new_item);
7277 AddQuantity(-split_quantity_new, false, true);
7278 new_item.SetQuantity(split_quantity_new, false, true);
7279 }
7280 }
7281 }
7282 else if (destination_entity && slot_id == -1)
7283 {
7284 if (quantity > stack_max)
7285 split_quantity_new = stack_max;
7286 else
7287 split_quantity_new = quantity;
7288
7289 if (ShouldSplitQuantity(split_quantity_new))
7290 {
7291 GameInventory destinationInventory = destination_entity.GetInventory();
7292 if (destinationInventory.FindFreeLocationFor(this, FindInventoryLocationType.ANY, loc))
7293 {
7294 Object o = destinationInventory.LocationCreateEntity(loc, GetType(), ECE_IN_INVENTORY, RF_DEFAULT);
7295 new_item = ItemBase.Cast(o);
7296 }
7297
7298 if (new_item)
7299 {
7300 new_item.SetResultOfSplit(true);
7301 MiscGameplayFunctions.TransferItemProperties(this, new_item);
7302 AddQuantity(-split_quantity_new, false, true);
7303 new_item.SetQuantity(split_quantity_new, false, true);
7304 }
7305 }
7306 }
7307 else
7308 {
7309 if (stack_max != 0)
7310 {
7311 if (stack_max < GetQuantity())
7312 {
7313 split_quantity_new = GetQuantity() - stack_max;
7314 }
7315
7316 if (split_quantity_new == 0)
7317 {
7318 if (!g_Game.IsMultiplayer())
7319 player.PhysicalPredictiveDropItem(this);
7320 else
7321 player.ServerDropEntity(this);
7322 return;
7323 }
7324
7325 if (ShouldSplitQuantity(split_quantity_new))
7326 {
7327 new_item = ItemBase.Cast(g_Game.CreateObjectEx(GetType(), player.GetWorldPosition(), ECE_PLACE_ON_SURFACE));
7328
7329 if (new_item)
7330 {
7331 new_item.SetResultOfSplit(true);
7332 MiscGameplayFunctions.TransferItemProperties(this, new_item);
7333 SetQuantity(split_quantity_new, false, true);
7334 new_item.SetQuantity(stack_max, false, true);
7335 new_item.PlaceOnSurface();
7336 }
7337 }
7338 }
7339 }
7340 }
7341
7342 override void SplitIntoStackMaxEx(EntityAI destination_entity, int slot_id)
7343 {
7344 float split_quantity_new;
7345 ItemBase new_item;
7346 float quantity = GetQuantity();
7347 float stack_max = GetTargetQuantityMax(slot_id);
7348 InventoryLocation loc = new InventoryLocation;
7349
7350 if (destination_entity && slot_id != -1 && InventorySlots.IsSlotIdValid(slot_id))
7351 {
7352 if (stack_max <= GetQuantity())
7353 split_quantity_new = stack_max;
7354 else
7355 split_quantity_new = GetQuantity();
7356
7357 if (ShouldSplitQuantity(split_quantity_new))
7358 {
7359 new_item = ItemBase.Cast(destination_entity.GetInventory().CreateAttachmentEx(this.GetType(), slot_id));
7360 if (new_item)
7361 {
7362 new_item.SetResultOfSplit(true);
7363 MiscGameplayFunctions.TransferItemProperties(this, new_item);
7364 AddQuantity(-split_quantity_new, false, true);
7365 new_item.SetQuantity(split_quantity_new, false, true);
7366 }
7367 }
7368 }
7369 else if (destination_entity && slot_id == -1)
7370 {
7371 if (quantity > stack_max)
7372 split_quantity_new = stack_max;
7373 else
7374 split_quantity_new = quantity;
7375
7376 if (ShouldSplitQuantity(split_quantity_new))
7377 {
7378 GameInventory destinationInventory = destination_entity.GetInventory();
7379 if (destinationInventory.FindFreeLocationFor(this, FindInventoryLocationType.ANY, loc))
7380 {
7381 Object o = destinationInventory.LocationCreateEntity(loc, GetType(), ECE_IN_INVENTORY, RF_DEFAULT);
7382 new_item = ItemBase.Cast(o);
7383 }
7384
7385 if (new_item)
7386 {
7387 new_item.SetResultOfSplit(true);
7388 MiscGameplayFunctions.TransferItemProperties(this, new_item);
7389 AddQuantity(-split_quantity_new, false, true);
7390 new_item.SetQuantity(split_quantity_new, false, true);
7391 }
7392 }
7393 }
7394 else
7395 {
7396 if (stack_max != 0)
7397 {
7398 if (stack_max < GetQuantity())
7399 {
7400 split_quantity_new = GetQuantity() - stack_max;
7401 }
7402
7403 if (ShouldSplitQuantity(split_quantity_new))
7404 {
7405 new_item = ItemBase.Cast(g_Game.CreateObjectEx(GetType(),GetWorldPosition(), ECE_PLACE_ON_SURFACE));
7406
7407 if (new_item)
7408 {
7409 new_item.SetResultOfSplit(true);
7410 MiscGameplayFunctions.TransferItemProperties(this, new_item);
7411 SetQuantity(split_quantity_new, false, true);
7412 new_item.SetQuantity(stack_max, false, true);
7413 new_item.PlaceOnSurface();
7414 }
7415 }
7416 }
7417 }
7418 }
7419
7420 void SplitIntoStackMaxToInventoryLocationClient(notnull InventoryLocation dst)
7421 {
7422 if (g_Game.IsClient())
7423 {
7424 if (ScriptInputUserData.CanStoreInputUserData())
7425 {
7426 ScriptInputUserData ctx = new ScriptInputUserData;
7428 ctx.Write(4);
7429 ItemBase thiz = this; // @NOTE: workaround for correct serialization
7430 ctx.Write(thiz);
7431 dst.WriteToContext(ctx);
7432 ctx.Send();
7433 }
7434 }
7435 else if (!g_Game.IsMultiplayer())
7436 {
7438 }
7439 }
7440
7441 void SplitIntoStackMaxCargoClient(EntityAI destination_entity, int idx, int row, int col)
7442 {
7443 if (g_Game.IsClient())
7444 {
7445 if (ScriptInputUserData.CanStoreInputUserData())
7446 {
7447 ScriptInputUserData ctx = new ScriptInputUserData;
7449 ctx.Write(2);
7450 ItemBase dummy = this; // @NOTE: workaround for correct serialization
7451 ctx.Write(dummy);
7452 ctx.Write(destination_entity);
7453 ctx.Write(true);
7454 ctx.Write(idx);
7455 ctx.Write(row);
7456 ctx.Write(col);
7457 ctx.Send();
7458 }
7459 }
7460 else if (!g_Game.IsMultiplayer())
7461 {
7462 SplitIntoStackMaxCargo(destination_entity, idx, row, col);
7463 }
7464 }
7465
7466 void SplitIntoStackMaxToInventoryLocation(notnull InventoryLocation dst)
7467 {
7469 }
7470
7471 ItemBase SplitIntoStackMaxToInventoryLocationEx(notnull InventoryLocation dst)
7472 {
7473 float quantity = GetQuantity();
7474 float split_quantity_new;
7475 ItemBase new_item;
7476 if (dst.IsValid())
7477 {
7478 int slot_id = dst.GetSlot();
7479 float stack_max = GetTargetQuantityMax(slot_id);
7480
7481 if (quantity > stack_max)
7482 split_quantity_new = stack_max;
7483 else
7484 split_quantity_new = quantity;
7485
7486 if (ShouldSplitQuantity(split_quantity_new))
7487 {
7488 new_item = ItemBase.Cast(GameInventory.LocationCreateEntity(dst, this.GetType(), ECE_IN_INVENTORY, RF_DEFAULT));
7489
7490 if (new_item)
7491 {
7492 new_item.SetResultOfSplit(true);
7493 MiscGameplayFunctions.TransferItemProperties(this,new_item);
7494 AddQuantity(-split_quantity_new, false, true);
7495 new_item.SetQuantity(split_quantity_new, false, true);
7496 }
7497
7498 return new_item;
7499 }
7500 }
7501
7502 return null;
7503 }
7504
7505 void SplitIntoStackMaxCargo(EntityAI destination_entity, int idx, int row, int col)
7506 {
7507 float quantity = GetQuantity();
7508 float split_quantity_new;
7509 ItemBase new_item;
7510 if (destination_entity)
7511 {
7512 float stackable = GetTargetQuantityMax();
7513 if (quantity > stackable)
7514 split_quantity_new = stackable;
7515 else
7516 split_quantity_new = quantity;
7517
7518 if (ShouldSplitQuantity(split_quantity_new))
7519 {
7520 new_item = ItemBase.Cast(destination_entity.GetInventory().CreateEntityInCargoEx(this.GetType(), idx, row, col, false));
7521 if (new_item)
7522 {
7523 new_item.SetResultOfSplit(true);
7524 MiscGameplayFunctions.TransferItemProperties(this,new_item);
7525 AddQuantity(-split_quantity_new, false, true);
7526 new_item.SetQuantity(split_quantity_new, false, true);
7527 }
7528 }
7529 }
7530 }
7531
7532 void SplitIntoStackMaxHandsClient(PlayerBase player)
7533 {
7534 if (g_Game.IsClient())
7535 {
7536 if (ScriptInputUserData.CanStoreInputUserData())
7537 {
7538 ScriptInputUserData ctx = new ScriptInputUserData;
7540 ctx.Write(3);
7541 ItemBase i1 = this; // @NOTE: workaround for correct serialization
7542 ctx.Write(i1);
7543 ItemBase destination_entity = this;
7544 ctx.Write(destination_entity);
7545 ctx.Write(true);
7546 ctx.Write(0);
7547 ctx.Send();
7548 }
7549 }
7550 else if (!g_Game.IsMultiplayer())
7551 {
7552 SplitIntoStackMaxHands(player);
7553 }
7554 }
7555
7556 void SplitIntoStackMaxHands(PlayerBase player)
7557 {
7558 float quantity = GetQuantity();
7559 float split_quantity_new;
7560 ref ItemBase new_item;
7561 if (player)
7562 {
7563 float stackable = GetTargetQuantityMax();
7564 if (quantity > stackable)
7565 split_quantity_new = stackable;
7566 else
7567 split_quantity_new = quantity;
7568
7569 if (ShouldSplitQuantity(split_quantity_new))
7570 {
7571 EntityAI in_hands = player.GetHumanInventory().CreateInHands(this.GetType());
7572 new_item = ItemBase.Cast(in_hands);
7573 if (new_item)
7574 {
7575 new_item.SetResultOfSplit(true);
7576 MiscGameplayFunctions.TransferItemProperties(this,new_item);
7577 AddQuantity(-split_quantity_new, false, true);
7578 new_item.SetQuantity(split_quantity_new, false, true);
7579 }
7580 }
7581 }
7582 }
7583
7584 void SplitItemToInventoryLocation(notnull InventoryLocation dst)
7585 {
7586 float quantity = GetQuantity();
7587 float split_quantity_new = Math.Floor(quantity * 0.5);
7588
7589 if (!ShouldSplitQuantity(split_quantity_new))
7590 return;
7591
7592 ItemBase new_item = ItemBase.Cast(GameInventory.LocationCreateEntity(dst, GetType(), ECE_IN_INVENTORY, RF_DEFAULT));
7593
7594 if (new_item)
7595 {
7596 if (new_item.GetQuantityMax() < split_quantity_new)
7597 {
7598 split_quantity_new = new_item.GetQuantityMax();
7599 }
7600
7601 new_item.SetResultOfSplit(true);
7602 MiscGameplayFunctions.TransferItemProperties(this, new_item);
7603
7604 if (dst.IsValid() && dst.GetType() == InventoryLocationType.ATTACHMENT && split_quantity_new > 1)
7605 {
7606 AddQuantity(-1, false, true);
7607 new_item.SetQuantity(1, false, true);
7608 }
7609 else
7610 {
7611 AddQuantity(-split_quantity_new, false, true);
7612 new_item.SetQuantity(split_quantity_new, false, true);
7613 }
7614 }
7615 }
7616
7617 void SplitItem(PlayerBase player)
7618 {
7619 float quantity = GetQuantity();
7620 float split_quantity_new = Math.Floor(quantity / 2);
7621
7622 if (!ShouldSplitQuantity(split_quantity_new))
7623 return;
7624
7625 InventoryLocation invloc = new InventoryLocation;
7626 bool found = player.GetInventory().FindFirstFreeLocationForNewEntity(GetType(), FindInventoryLocationType.ATTACHMENT, invloc);
7627
7628 ItemBase new_item;
7629 new_item = player.CreateCopyOfItemInInventoryOrGroundEx(this, true);
7630
7631 if (new_item)
7632 {
7633 if (new_item.GetQuantityMax() < split_quantity_new)
7634 {
7635 split_quantity_new = new_item.GetQuantityMax();
7636 }
7637 if (found && invloc.IsValid() && invloc.GetType() == InventoryLocationType.ATTACHMENT && split_quantity_new > 1)
7638 {
7639 AddQuantity(-1, false, true);
7640 new_item.SetQuantity(1, false, true);
7641 }
7642 else if (split_quantity_new > 1)
7643 {
7644 AddQuantity(-split_quantity_new, false, true);
7645 new_item.SetQuantity(split_quantity_new, false, true);
7646 }
7647 }
7648 }
7649
7651 void OnQuantityChanged(float delta)
7652 {
7653 SetWeightDirty();
7654 ItemBase parent = ItemBase.Cast(GetHierarchyParent());
7655
7656 if (parent)
7657 parent.OnAttachmentQuantityChangedEx(this, delta);
7658
7659 if (IsLiquidContainer())
7660 {
7661 if (GetQuantityNormalized() <= 0.0)
7662 {
7664 }
7665 else if (GetLiquidType() == LIQUID_NONE)
7666 {
7667 ErrorEx("Undefined liquid type quantity changed, please define liquid type first! Using init value.",ErrorExSeverity.INFO);
7669 }
7670 }
7671 }
7672
7675 {
7676 // insert code here
7677 }
7678
7680 void OnAttachmentQuantityChangedEx(ItemBase item , float delta)
7681 {
7683 }
7684
7685 override void EEHealthLevelChanged(int oldLevel, int newLevel, string zone)
7686 {
7687 super.EEHealthLevelChanged(oldLevel,newLevel,zone);
7688
7689 if (g_Game.IsServer())
7690 {
7691 if (newLevel == GameConstants.STATE_RUINED)
7692 {
7694 EntityAI parent = GetHierarchyParent();
7695 if (parent && parent.IsFireplace())
7696 {
7697 CargoBase cargo = GetInventory().GetCargo();
7698 if (cargo)
7699 {
7700 for (int i = 0; i < cargo.GetItemCount(); ++i)
7701 {
7702 parent.GetInventory().TakeEntityToInventory(InventoryMode.SERVER, FindInventoryLocationType.CARGO, cargo.GetItem(i));
7703 }
7704 }
7705 }
7706 }
7707
7708 if (IsResultOfSplit())
7709 {
7710 // reset the splitting result flag, return to normal item behavior
7711 SetResultOfSplit(false);
7712 return;
7713 }
7714
7715 if (m_Cleanness != 0 && oldLevel < newLevel && newLevel != 0)
7716 {
7717 SetCleanness(0);//unclean the item upon damage dealt
7718 }
7719 }
7720 }
7721
7722 // just the split? TODO: verify
7723 override void OnRightClick()
7724 {
7725 super.OnRightClick();
7726
7727 if (CanBeSplit() && !GetDayZGame().IsLeftCtrlDown() && !g_Game.GetPlayer().GetInventory().HasInventoryReservation(this,null))
7728 {
7729 if (g_Game.IsClient())
7730 {
7731 if (ScriptInputUserData.CanStoreInputUserData())
7732 {
7733 EntityAI root = GetHierarchyRoot();
7734 Man playerOwner = GetHierarchyRootPlayer();
7735 InventoryLocation dst = new InventoryLocation;
7736
7737 // 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
7738 if (!playerOwner && root && root == this)
7739 {
7741 }
7742 else
7743 {
7744 // 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
7745 GetInventory().GetCurrentInventoryLocation(dst);
7746 if (!dst.GetParent() || dst.GetParent() && !dst.GetParent().GetInventory().FindFreeLocationFor(this, FindInventoryLocationType.CARGO, dst))
7747 {
7748 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
7749 if (!player.GetInventory().FindFreeLocationFor(this, FindInventoryLocationType.CARGO, dst) || !playerOwner)
7750 {
7752 }
7753 else
7754 {
7755 dst.SetCargo(dst.GetParent(), this, dst.GetIdx(), dst.GetRow(), dst.GetCol(), dst.GetFlip());
7756 /* hacky solution to check reservation of "this" item instead of null since the gamecode is checking null against null and returning reservation=true incorrectly
7757 this shouldnt cause issues within this scope*/
7758 if (g_Game.GetPlayer().GetInventory().HasInventoryReservation(this, dst))
7759 {
7761 }
7762 else
7763 {
7764 g_Game.GetPlayer().GetInventory().AddInventoryReservationEx(null, dst, GameInventory.c_InventoryReservationTimeoutShortMS);
7765 }
7766 }
7767 }
7768 }
7769
7770 ScriptInputUserData ctx = new ScriptInputUserData;
7772 ctx.Write(4);
7773 ItemBase thiz = this; // @NOTE: workaround for correct serialization
7774 ctx.Write(thiz);
7775 dst.WriteToContext(ctx);
7776 ctx.Write(true); // dummy
7777 ctx.Send();
7778 }
7779 }
7780 else if (!g_Game.IsMultiplayer())
7781 {
7782 SplitItem(PlayerBase.Cast(g_Game.GetPlayer()));
7783 }
7784 }
7785 }
7786
7787 protected void SetInventoryLocationToVicinityOrCurrent(EntityAI root, inout InventoryLocation dst)
7788 {
7789 if (root)
7790 {
7791 vector m4[4];
7792 root.GetTransform(m4);
7793 dst.SetGround(this, m4);
7794 }
7795 else
7796 {
7797 GetInventory().GetCurrentInventoryLocation(dst);
7798 }
7799 }
7800
7801 override bool CanBeCombined(EntityAI other_item, bool reservation_check = true, bool stack_max_limit = false)
7802 {
7803 //TODO: delete check zero quantity check after fix double posts hands fsm events
7804 if (!other_item || GetType() != other_item.GetType() || (IsFullQuantity() && other_item.GetQuantity() > 0) || other_item == this)
7805 return false;
7806
7807 if (GetHealthLevel() == GameConstants.STATE_RUINED || other_item.GetHealthLevel() == GameConstants.STATE_RUINED)
7808 return false;
7809
7810 //can_this_be_combined = ConfigGetBool("canBeSplit");
7812 return false;
7813
7814
7815 Magazine mag = Magazine.Cast(this);
7816 if (mag)
7817 {
7818 if (mag.GetAmmoCount() >= mag.GetAmmoMax())
7819 return false;
7820
7821 if (stack_max_limit)
7822 {
7823 Magazine other_mag = Magazine.Cast(other_item);
7824 if (other_item)
7825 {
7826 if (mag.GetAmmoCount() + other_mag.GetAmmoCount() > mag.GetAmmoMax())
7827 return false;
7828 }
7829
7830 }
7831 }
7832 else
7833 {
7834 //TODO: delete check zero quantity check after fix double posts hands fsm events
7835 if (GetQuantity() >= GetQuantityMax() && other_item.GetQuantity() > 0 )
7836 return false;
7837
7838 if (stack_max_limit && (GetQuantity() + other_item.GetQuantity() > GetQuantityMax()))
7839 return false;
7840 }
7841
7842 PlayerBase player = null;
7843 if (CastTo(player, GetHierarchyRootPlayer())) //false when attached to player's attachment slot
7844 {
7845 if (player.GetInventory().HasAttachment(this))
7846 return false;
7847
7848 if (player.IsItemsToDelete())
7849 return false;
7850 }
7851
7852 if (reservation_check && (GetInventory().HasInventoryReservation(this, null) || other_item.GetInventory().HasInventoryReservation(other_item, null)))
7853 return false;
7854
7855 int slotID;
7856 string slotName;
7857 if (GetInventory().GetCurrentAttachmentSlotInfo(slotID,slotName) && GetHierarchyParent().GetInventory().GetSlotLock(slotID))
7858 return false;
7859
7860 return true;
7861 }
7862
7863 bool IsCombineAll(ItemBase other_item, bool use_stack_max = false)
7864 {
7865 return ComputeQuantityUsed(other_item, use_stack_max) == other_item.GetQuantity();
7866 }
7867
7868 bool IsResultOfSplit()
7869 {
7870 return m_IsResultOfSplit;
7871 }
7872
7873 void SetResultOfSplit(bool value)
7874 {
7875 m_IsResultOfSplit = value;
7876 }
7877
7878 int ComputeQuantityUsed(ItemBase other_item, bool use_stack_max = true)
7879 {
7880 return ComputeQuantityUsedEx(other_item, use_stack_max);
7881 }
7882
7883 float ComputeQuantityUsedEx(ItemBase other_item, bool use_stack_max = true)
7884 {
7885 float other_item_quantity = other_item.GetQuantity();
7886 float this_free_space;
7887
7888 float stack_max = GetQuantityMax();
7889
7890 this_free_space = stack_max - GetQuantity();
7891
7892 if (other_item_quantity > this_free_space)
7893 {
7894 return this_free_space;
7895 }
7896 else
7897 {
7898 return other_item_quantity;
7899 }
7900 }
7901
7902 override void CombineItemsEx(EntityAI entity2, bool use_stack_max = true)
7903 {
7904 CombineItems(ItemBase.Cast(entity2),use_stack_max);
7905 }
7906
7907 void CombineItems(ItemBase other_item, bool use_stack_max = true)
7908 {
7909 if (!CanBeCombined(other_item, false))
7910 return;
7911
7912 if (!IsMagazine() && other_item)
7913 {
7914 float quantity_used = ComputeQuantityUsedEx(other_item,use_stack_max);
7915 if (quantity_used != 0)
7916 {
7917 float hp1 = GetHealth01("","");
7918 float hp2 = other_item.GetHealth01("","");
7919 float hpResult = ((hp1*GetQuantity()) + (hp2*quantity_used));
7920 hpResult = hpResult / (GetQuantity() + quantity_used);
7921
7922 hpResult *= GetMaxHealth();
7923 Math.Round(hpResult);
7924 SetHealth("", "Health", hpResult);
7925
7926 AddQuantity(quantity_used);
7927 other_item.AddQuantity(-quantity_used);
7928 }
7929 }
7930 OnCombine(other_item);
7931 }
7932
7933 void OnCombine(ItemBase other_item)
7934 {
7935 #ifdef SERVER
7936 if (!GetHierarchyRootPlayer() && GetHierarchyParent())
7937 GetHierarchyParent().IncreaseLifetimeUp();
7938 #endif
7939 };
7940
7941 void GetRecipesActions(Man player, out TSelectableActionInfoArray outputList)
7942 {
7943 PlayerBase p = PlayerBase.Cast(player);
7944
7945 array<int> recipesIds = p.m_Recipes;
7946 PluginRecipesManager moduleRecipesManager = PluginRecipesManager.Cast(GetPlugin(PluginRecipesManager));
7947 if (moduleRecipesManager)
7948 {
7949 EntityAI itemInHands = player.GetEntityInHands();
7950 moduleRecipesManager.GetValidRecipes(ItemBase.Cast(this), ItemBase.Cast(itemInHands), recipesIds, p);
7951 }
7952
7953 for (int i = 0;i < recipesIds.Count(); i++)
7954 {
7955 int key = recipesIds.Get(i);
7956 string recipeName = moduleRecipesManager.GetRecipeName(key);
7957 outputList.Insert(new TSelectableActionInfo(SAT_CRAFTING, key, recipeName));
7958 }
7959 }
7960
7961 // -------------------------------------------------------------------------
7962 override void GetDebugActions(out TSelectableActionInfoArrayEx outputList)
7963 {
7964 super.GetDebugActions(outputList);
7965
7966 //quantity
7967 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_QUANTITY, "Quantity +20%", FadeColors.LIGHT_GREY));
7968 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_QUANTITY, "Quantity -20%", FadeColors.LIGHT_GREY));
7969 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SET_QUANTITY_0, "Set Quantity 0", FadeColors.LIGHT_GREY));
7970 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SET_MAX_QUANTITY, "Set Quantity Max", FadeColors.LIGHT_GREY));
7971 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
7972
7973 //health
7974 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_HEALTH, "Health +20%", FadeColors.LIGHT_GREY));
7975 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_HEALTH, "Health -20%", FadeColors.LIGHT_GREY));
7976 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.DESTROY_HEALTH, "Health 0", FadeColors.LIGHT_GREY));
7977 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
7978 //temperature
7979 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_TEMPERATURE, "Temperature +20", FadeColors.LIGHT_GREY));
7980 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_TEMPERATURE, "Temperature -20", FadeColors.LIGHT_GREY));
7981 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.FLIP_FROZEN, "Toggle Frozen", FadeColors.LIGHT_GREY));
7982 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
7983
7984 //wet
7985 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ADD_WETNESS, "Wetness +20", FadeColors.LIGHT_GREY));
7986 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.REMOVE_WETNESS, "Wetness -20", FadeColors.LIGHT_GREY));
7987 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
7988
7989 //liquidtype
7990 if (IsLiquidContainer())
7991 {
7992 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.LIQUIDTYPE_UP, "LiquidType Next", FadeColors.LIGHT_GREY));
7993 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.LIQUIDTYPE_DOWN, "LiquidType Previous", FadeColors.LIGHT_GREY));
7994 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
7995 }
7996
7997 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.MAKE_SPECIAL, "Make Special", FadeColors.LIGHT_GREY));
7998 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
7999
8000 // watch
8001 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.WATCH_ITEM, "Watch (CTRL-Z)", FadeColors.LIGHT_GREY));
8002 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.WATCH_PLAYER, "Watch Player", FadeColors.LIGHT_GREY));
8003 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
8004
8005 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.DELETE, "Delete", FadeColors.RED));
8006
8007 InventoryLocation loc = new InventoryLocation();
8008 GetInventory().GetCurrentInventoryLocation(loc);
8009 if (!loc || loc.GetType() == InventoryLocationType.GROUND)
8010 {
8011 if (Gizmo_IsSupported())
8012 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.GIZMO_OBJECT, "Gizmo Object", FadeColors.LIGHT_GREY));
8013 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.GIZMO_PHYSICS, "Gizmo Physics (SP Only)", FadeColors.LIGHT_GREY)); // intentionally allowed for testing physics desync
8014 }
8015
8016 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
8017 }
8018
8019 // -------------------------------------------------------------------------
8020 // -------------------------------------------------------------------------
8021 // -------------------------------------------------------------------------
8022 override bool OnAction(int action_id, Man player, ParamsReadContext ctx)
8023 {
8024 super.OnAction(action_id, player, ctx);
8025
8026 if (g_Game.IsClient() || !g_Game.IsMultiplayer())
8027 {
8028 switch (action_id)
8029 {
8030 case EActions.GIZMO_OBJECT:
8031 if (GetGizmoApi())
8032 GetGizmoApi().SelectObject(this);
8033 return true;
8034 case EActions.GIZMO_PHYSICS:
8035 if (GetGizmoApi())
8036 GetGizmoApi().SelectPhysics(GetPhysics());
8037 return true;
8038 }
8039 }
8040
8041 if (g_Game.IsServer())
8042 {
8043 switch (action_id)
8044 {
8045 case EActions.DELETE:
8046 Delete();
8047 return true;
8048 }
8049 }
8050
8051 if (action_id >= EActions.RECIPES_RANGE_START && action_id < EActions.RECIPES_RANGE_END)
8052 {
8053 PluginRecipesManager plugin_recipes_manager = PluginRecipesManager.Cast(GetPlugin(PluginRecipesManager));
8054 int idWithoutOffset = action_id - EActions.RECIPES_RANGE_START;
8055 PlayerBase p = PlayerBase.Cast(player);
8056 if (EActions.RECIPES_RANGE_START < 1000)
8057 {
8058 float anim_length = plugin_recipes_manager.GetRecipeLengthInSecs(idWithoutOffset);
8059 float specialty_weight = plugin_recipes_manager.GetRecipeSpecialty(idWithoutOffset);
8060 }
8061 }
8062 #ifndef SERVER
8063 else if (action_id == EActions.WATCH_PLAYER)
8064 {
8065 PluginDeveloper.SetDeveloperItemClientEx(player);
8066 }
8067 #endif
8068 if (g_Game.IsServer())
8069 {
8070 if (action_id >= EActions.DEBUG_ITEM_WATCH_BUTTON_RANGE_START && action_id < EActions.DEBUG_ITEM_WATCH_BUTTON_RANGE_END)
8071 {
8072 int id = action_id - EActions.DEBUG_ITEM_WATCH_BUTTON_RANGE_START;
8073 OnDebugButtonPressServer(id + 1);
8074 }
8075
8076 else if (action_id >= EActions.DEBUG_AGENTS_RANGE_INJECT_START && action_id < EActions.DEBUG_AGENTS_RANGE_INJECT_END)
8077 {
8078 int agent_id = action_id - EActions.DEBUG_AGENTS_RANGE_INJECT_START;
8079 InsertAgent(agent_id,100);
8080 }
8081
8082 else if (action_id >= EActions.DEBUG_AGENTS_RANGE_REMOVE_START && action_id < EActions.DEBUG_AGENTS_RANGE_REMOVE_END)
8083 {
8084 int agent_id2 = action_id - EActions.DEBUG_AGENTS_RANGE_REMOVE_START;
8085 RemoveAgent(agent_id2);
8086 }
8087
8088 else if (action_id == EActions.ADD_QUANTITY)
8089 {
8090 if (IsMagazine())
8091 {
8092 Magazine mag = Magazine.Cast(this);
8093 mag.ServerSetAmmoCount(mag.GetAmmoCount() + mag.GetAmmoMax() * 0.2);
8094 }
8095 else
8096 {
8097 AddQuantity(GetQuantityMax() * 0.2);
8098 }
8099
8100 if (m_EM)
8101 {
8102 m_EM.AddEnergy(m_EM.GetEnergyMax() * 0.2);
8103 }
8104 //PrintVariables();
8105 }
8106
8107 else if (action_id == EActions.REMOVE_QUANTITY) //Quantity -20%
8108 {
8109 if (IsMagazine())
8110 {
8111 Magazine mag2 = Magazine.Cast(this);
8112 mag2.ServerSetAmmoCount(mag2.GetAmmoCount() - mag2.GetAmmoMax() * 0.2);
8113 }
8114 else
8115 {
8116 AddQuantity(- GetQuantityMax() * 0.2);
8117 }
8118 if (m_EM)
8119 {
8120 m_EM.AddEnergy(- m_EM.GetEnergyMax() * 0.2);
8121 }
8122 //PrintVariables();
8123 }
8124
8125 else if (action_id == EActions.SET_QUANTITY_0) //SetMaxQuantity
8126 {
8127 SetQuantity(0);
8128
8129 if (m_EM)
8130 {
8131 m_EM.SetEnergy(0);
8132 }
8133 }
8134
8135 else if (action_id == EActions.SET_MAX_QUANTITY) //SetMaxQuantity
8136 {
8138
8139 if (m_EM)
8140 {
8141 m_EM.SetEnergy(m_EM.GetEnergyMax());
8142 }
8143 }
8144
8145 else if (action_id == EActions.ADD_HEALTH)
8146 {
8147 AddHealth("","",GetMaxHealth("","Health")/5);
8148 }
8149 else if (action_id == EActions.REMOVE_HEALTH)
8150 {
8151 AddHealth("","",-GetMaxHealth("","Health")/5);
8152 }
8153 else if (action_id == EActions.DESTROY_HEALTH)
8154 {
8155 SetHealth01("","",0);
8156 }
8157 else if (action_id == EActions.WATCH_ITEM)
8158 {
8160 mid.RegisterDebugItem(ItemBase.Cast(this), PlayerBase.Cast(player));
8161 #ifdef DEVELOPER
8162 SetDebugDeveloper_item(this);
8163 #endif
8164 }
8165
8166 else if (action_id == EActions.ADD_TEMPERATURE)
8167 {
8168 AddTemperature(20);
8169 //PrintVariables();
8170 }
8171
8172 else if (action_id == EActions.REMOVE_TEMPERATURE)
8173 {
8174 AddTemperature(-20);
8175 //PrintVariables();
8176 }
8177
8178 else if (action_id == EActions.FLIP_FROZEN)
8179 {
8180 SetFrozen(!GetIsFrozen());
8181 //PrintVariables();
8182 }
8183
8184 else if (action_id == EActions.ADD_WETNESS)
8185 {
8186 AddWet(GetWetMax()/5);
8187 //PrintVariables();
8188 }
8189
8190 else if (action_id == EActions.REMOVE_WETNESS)
8191 {
8192 AddWet(-GetWetMax()/5);
8193 //PrintVariables();
8194 }
8195
8196 else if (action_id == EActions.LIQUIDTYPE_UP)
8197 {
8198 int curr_type = GetLiquidType();
8199 SetLiquidType(curr_type * 2);
8200 //AddWet(1);
8201 //PrintVariables();
8202 }
8203
8204 else if (action_id == EActions.LIQUIDTYPE_DOWN)
8205 {
8206 int curr_type2 = GetLiquidType();
8207 SetLiquidType(curr_type2 / 2);
8208 }
8209
8210 else if (action_id == EActions.MAKE_SPECIAL)
8211 {
8212 auto debugParams = DebugSpawnParams.WithPlayer(player);
8213 OnDebugSpawnEx(debugParams);
8214 }
8215
8216 }
8217
8218
8219 return false;
8220 }
8221
8222 // -------------------------------------------------------------------------
8223
8224
8227 void OnActivatedByTripWire();
8228
8230 void OnActivatedByItem(notnull ItemBase item);
8231
8232 //----------------------------------------------------------------
8233 //returns true if item is able to explode when put in fire
8234 bool CanExplodeInFire()
8235 {
8236 return false;
8237 }
8238
8239 //----------------------------------------------------------------
8240 bool CanEat()
8241 {
8242 return true;
8243 }
8244
8245 //----------------------------------------------------------------
8246 override bool IsIgnoredByConstruction()
8247 {
8248 return true;
8249 }
8250
8251 //----------------------------------------------------------------
8252 //has FoodStages in config?
8253 bool HasFoodStage()
8254 {
8255 string config_path = string.Format("CfgVehicles %1 Food FoodStages", GetType());
8256 return g_Game.ConfigIsExisting(config_path);
8257 }
8258
8260 FoodStage GetFoodStage()
8261 {
8262 return null;
8263 }
8264
8265 bool CanBeCooked()
8266 {
8267 return false;
8268 }
8269
8270 bool CanBeCookedOnStick()
8271 {
8272 return false;
8273 }
8274
8276 void RefreshAudioVisualsOnClient( CookingMethodType cooking_method, bool is_done, bool is_empty, bool is_burned );
8278
8279 //----------------------------------------------------------------
8280 bool CanRepair(ItemBase item_repair_kit)
8281 {
8282 PluginRepairing module_repairing = PluginRepairing.Cast(GetPlugin(PluginRepairing));
8283 return module_repairing.CanRepair(this, item_repair_kit);
8284 }
8285
8286 //----------------------------------------------------------------
8287 bool Repair(PlayerBase player, ItemBase item_repair_kit, float specialty_weight)
8288 {
8289 PluginRepairing module_repairing = PluginRepairing.Cast(GetPlugin(PluginRepairing));
8290 return module_repairing.Repair(player, this, item_repair_kit, specialty_weight);
8291 }
8292
8293 //----------------------------------------------------------------
8294 int GetItemSize()
8295 {
8296 /*
8297 vector v_size = this.ConfigGetVector("itemSize");
8298 int v_size_x = v_size[0];
8299 int v_size_y = v_size[1];
8300 int size = v_size_x * v_size_y;
8301 return size;
8302 */
8303
8304 return 1;
8305 }
8306
8307 //----------------------------------------------------------------
8308 //Override for allowing seemingly unallowed moves when two clients send a conflicting message simultaneously
8309 bool CanBeMovedOverride()
8310 {
8311 return m_CanBeMovedOverride;
8312 }
8313
8314 //----------------------------------------------------------------
8315 //Override for allowing seemingly unallowed moves when two clients send a conflicting message simultaneously
8316 void SetCanBeMovedOverride(bool setting)
8317 {
8318 m_CanBeMovedOverride = setting;
8319 }
8320
8321 //----------------------------------------------------------------
8329 void MessageToOwnerStatus(string text)
8330 {
8331 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
8332
8333 if (player)
8334 {
8335 player.MessageStatus(text);
8336 }
8337 }
8338
8339 //----------------------------------------------------------------
8347 void MessageToOwnerAction(string text)
8348 {
8349 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
8350
8351 if (player)
8352 {
8353 player.MessageAction(text);
8354 }
8355 }
8356
8357 //----------------------------------------------------------------
8365 void MessageToOwnerFriendly(string text)
8366 {
8367 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
8368
8369 if (player)
8370 {
8371 player.MessageFriendly(text);
8372 }
8373 }
8374
8375 //----------------------------------------------------------------
8383 void MessageToOwnerImportant(string text)
8384 {
8385 PlayerBase player = PlayerBase.Cast(this.GetHierarchyRootPlayer());
8386
8387 if (player)
8388 {
8389 player.MessageImportant(text);
8390 }
8391 }
8392
8393 override bool IsItemBase()
8394 {
8395 return true;
8396 }
8397
8398 // Checks if item is of questioned kind
8399 override bool KindOf(string tag)
8400 {
8401 bool found = false;
8402 string item_name = this.GetType();
8403 ref TStringArray item_tag_array = new TStringArray;
8404 g_Game.ConfigGetTextArray("cfgVehicles " + item_name + " itemInfo", item_tag_array);
8405
8406 int array_size = item_tag_array.Count();
8407 for (int i = 0; i < array_size; i++)
8408 {
8409 if (item_tag_array.Get(i) == tag)
8410 {
8411 found = true;
8412 break;
8413 }
8414 }
8415 return found;
8416 }
8417
8418
8419 override void OnRPC(PlayerIdentity sender, int rpc_type,ParamsReadContext ctx)
8420 {
8421 //Debug.Log("OnRPC called");
8422 super.OnRPC(sender, rpc_type,ctx);
8423
8424 //Play soundset for attachment locking (ActionLockAttachment.c)
8425 switch (rpc_type)
8426 {
8427 #ifndef SERVER
8428 case ERPCs.RPC_SOUND_LOCK_ATTACH:
8429 Param2<bool, string> p = new Param2<bool, string>(false, "");
8430
8431 if (!ctx.Read(p))
8432 return;
8433
8434 bool play = p.param1;
8435 string soundSet = p.param2;
8436
8437 if (play)
8438 {
8439 if (m_LockingSound)
8440 {
8442 {
8443 m_LockingSound = SEffectManager.PlaySound(soundSet, GetPosition(), 0, 0, true);
8444 }
8445 }
8446 else
8447 {
8448 m_LockingSound = SEffectManager.PlaySound(soundSet, GetPosition(), 0, 0, true);
8449 }
8450 }
8451 else
8452 {
8453 SEffectManager.DestroyEffect(m_LockingSound);
8454 }
8455
8456 break;
8457 #endif
8458
8459 }
8460
8461 if (GetWrittenNoteData())
8462 {
8463 GetWrittenNoteData().OnRPC(sender, rpc_type,ctx);
8464 }
8465 }
8466
8467 //-----------------------------
8468 // VARIABLE MANIPULATION SYSTEM
8469 //-----------------------------
8470 int NameToID(string name)
8471 {
8472 PluginVariables plugin = PluginVariables.Cast(GetPlugin(PluginVariables));
8473 return plugin.GetID(name);
8474 }
8475
8476 string IDToName(int id)
8477 {
8478 PluginVariables plugin = PluginVariables.Cast(GetPlugin(PluginVariables));
8479 return plugin.GetName(id);
8480 }
8481
8483 void OnSyncVariables(ParamsReadContext ctx)//with ID optimization
8484 {
8485 //Debug.Log("OnSyncVariables called for item: "+ ToString(this.GetType()),"varSync");
8486 //read the flags
8487 int varFlags;
8488 if (!ctx.Read(varFlags))
8489 return;
8490
8491 if (varFlags & ItemVariableFlags.FLOAT)
8492 {
8493 ReadVarsFromCTX(ctx);
8494 }
8495 }
8496
8497 override void SerializeNumericalVars(array<float> floats_out)
8498 {
8499 //some variables handled on EntityAI level already!
8500 super.SerializeNumericalVars(floats_out);
8501
8502 // the order of serialization must be the same as the order of de-serialization
8503 //--------------------------------------------
8504 if (IsVariableSet(VARIABLE_QUANTITY))
8505 {
8506 floats_out.Insert(m_VarQuantity);
8507 }
8508 //--------------------------------------------
8509 if (IsVariableSet(VARIABLE_WET))
8510 {
8511 floats_out.Insert(m_VarWet);
8512 }
8513 //--------------------------------------------
8514 if (IsVariableSet(VARIABLE_LIQUIDTYPE))
8515 {
8516 floats_out.Insert(m_VarLiquidType);
8517 }
8518 //--------------------------------------------
8519 if (IsVariableSet(VARIABLE_COLOR))
8520 {
8521 floats_out.Insert(m_ColorComponentR);
8522 floats_out.Insert(m_ColorComponentG);
8523 floats_out.Insert(m_ColorComponentB);
8524 floats_out.Insert(m_ColorComponentA);
8525 }
8526 //--------------------------------------------
8527 if (IsVariableSet(VARIABLE_CLEANNESS))
8528 {
8529 floats_out.Insert(m_Cleanness);
8530 }
8531 }
8532
8533 override void DeSerializeNumericalVars(array<float> floats)
8534 {
8535 //some variables handled on EntityAI level already!
8536 super.DeSerializeNumericalVars(floats);
8537
8538 // the order of serialization must be the same as the order of de-serialization
8539 int index = 0;
8540 int mask = Math.Round(floats.Get(index));
8541
8542 index++;
8543 //--------------------------------------------
8544 if (mask & VARIABLE_QUANTITY)
8545 {
8546 if (m_IsStoreLoad)
8547 {
8548 SetStoreLoadedQuantity(floats.Get(index));
8549 }
8550 else
8551 {
8552 float quantity = floats.Get(index);
8553 SetQuantity(quantity, true, false, false, false);
8554 }
8555 index++;
8556 }
8557 //--------------------------------------------
8558 if (mask & VARIABLE_WET)
8559 {
8560 float wet = floats.Get(index);
8561 SetWet(wet);
8562 index++;
8563 }
8564 //--------------------------------------------
8565 if (mask & VARIABLE_LIQUIDTYPE)
8566 {
8567 int liquidtype = Math.Round(floats.Get(index));
8568 SetLiquidType(liquidtype);
8569 index++;
8570 }
8571 //--------------------------------------------
8572 if (mask & VARIABLE_COLOR)
8573 {
8574 m_ColorComponentR = Math.Round(floats.Get(index));
8575 index++;
8576 m_ColorComponentG = Math.Round(floats.Get(index));
8577 index++;
8578 m_ColorComponentB = Math.Round(floats.Get(index));
8579 index++;
8580 m_ColorComponentA = Math.Round(floats.Get(index));
8581 index++;
8582 }
8583 //--------------------------------------------
8584 if (mask & VARIABLE_CLEANNESS)
8585 {
8586 int cleanness = Math.Round(floats.Get(index));
8587 SetCleanness(cleanness);
8588 index++;
8589 }
8590 }
8591
8592 override void WriteVarsToCTX(ParamsWriteContext ctx)
8593 {
8594 super.WriteVarsToCTX(ctx);
8595
8596 //--------------------------------------------
8597 if (IsVariableSet(VARIABLE_QUANTITY))
8598 {
8599 ctx.Write(GetQuantity());
8600 }
8601 //--------------------------------------------
8602 if (IsVariableSet(VARIABLE_WET))
8603 {
8604 ctx.Write(GetWet());
8605 }
8606 //--------------------------------------------
8607 if (IsVariableSet(VARIABLE_LIQUIDTYPE))
8608 {
8609 ctx.Write(GetLiquidType());
8610 }
8611 //--------------------------------------------
8612 if (IsVariableSet(VARIABLE_COLOR))
8613 {
8614 int r,g,b,a;
8615 GetColor(r,g,b,a);
8616 ctx.Write(r);
8617 ctx.Write(g);
8618 ctx.Write(b);
8619 ctx.Write(a);
8620 }
8621 //--------------------------------------------
8622 if (IsVariableSet(VARIABLE_CLEANNESS))
8623 {
8624 ctx.Write(GetCleanness());
8625 }
8626 }
8627
8628 override bool ReadVarsFromCTX(ParamsReadContext ctx, int version = -1)//with ID optimization
8629 {
8630 if (!super.ReadVarsFromCTX(ctx,version))
8631 return false;
8632
8633 int intValue;
8634 float value;
8635
8636 if (version < 140)
8637 {
8638 if (!ctx.Read(intValue))
8639 return false;
8640
8641 m_VariablesMask = intValue;
8642 }
8643
8644 if (m_VariablesMask & VARIABLE_QUANTITY)
8645 {
8646 if (!ctx.Read(value))
8647 return false;
8648
8649 if (IsStoreLoad())
8650 {
8652 }
8653 else
8654 {
8655 SetQuantity(value, true, false, false, false);
8656 }
8657 }
8658 //--------------------------------------------
8659 if (version < 140)
8660 {
8661 if (m_VariablesMask & VARIABLE_TEMPERATURE)
8662 {
8663 if (!ctx.Read(value))
8664 return false;
8665 SetTemperatureDirect(value);
8666 }
8667 }
8668 //--------------------------------------------
8669 if (m_VariablesMask & VARIABLE_WET)
8670 {
8671 if (!ctx.Read(value))
8672 return false;
8673 SetWet(value);
8674 }
8675 //--------------------------------------------
8676 if (m_VariablesMask & VARIABLE_LIQUIDTYPE)
8677 {
8678 if (!ctx.Read(intValue))
8679 return false;
8680 SetLiquidType(intValue);
8681 }
8682 //--------------------------------------------
8683 if (m_VariablesMask & VARIABLE_COLOR)
8684 {
8685 int r,g,b,a;
8686 if (!ctx.Read(r))
8687 return false;
8688 if (!ctx.Read(g))
8689 return false;
8690 if (!ctx.Read(b))
8691 return false;
8692 if (!ctx.Read(a))
8693 return false;
8694
8695 SetColor(r,g,b,a);
8696 }
8697 //--------------------------------------------
8698 if (m_VariablesMask & VARIABLE_CLEANNESS)
8699 {
8700 if (!ctx.Read(intValue))
8701 return false;
8702 SetCleanness(intValue);
8703 }
8704 //--------------------------------------------
8705 if (version >= 138 && version < 140)
8706 {
8707 if (m_VariablesMask & VARIABLE_TEMPERATURE)
8708 {
8709 if (!ctx.Read(intValue))
8710 return false;
8711 SetFrozen(intValue);
8712 }
8713 }
8714
8715 return true;
8716 }
8717
8718 //----------------------------------------------------------------
8719 override bool OnStoreLoad(ParamsReadContext ctx, int version)
8720 {
8721 m_IsStoreLoad = true;
8723 {
8724 m_FixDamageSystemInit = true;
8725 }
8726
8727 if (!super.OnStoreLoad(ctx, version))
8728 {
8729 m_IsStoreLoad = false;
8730 return false;
8731 }
8732
8733 if (version >= 114)
8734 {
8735 bool hasQuickBarIndexSaved;
8736
8737 if (!ctx.Read(hasQuickBarIndexSaved))
8738 {
8739 m_IsStoreLoad = false;
8740 return false;
8741 }
8742
8743 if (hasQuickBarIndexSaved)
8744 {
8745 int itmQBIndex;
8746
8747 //Load quickbar item bind
8748 if (!ctx.Read(itmQBIndex))
8749 {
8750 m_IsStoreLoad = false;
8751 return false;
8752 }
8753
8754 PlayerBase parentPlayer = PlayerBase.Cast(GetHierarchyRootPlayer());
8755 if (itmQBIndex != -1 && parentPlayer)
8756 parentPlayer.SetLoadedQuickBarItemBind(this, itmQBIndex);
8757 }
8758 }
8759 else
8760 {
8761 // Backup of how it used to be
8762 PlayerBase player;
8763 int itemQBIndex;
8764 if (version == int.MAX)
8765 {
8766 if (!ctx.Read(itemQBIndex))
8767 {
8768 m_IsStoreLoad = false;
8769 return false;
8770 }
8771 }
8772 else if (Class.CastTo(player, GetHierarchyRootPlayer()))
8773 {
8774 //Load quickbar item bind
8775 if (!ctx.Read(itemQBIndex))
8776 {
8777 m_IsStoreLoad = false;
8778 return false;
8779 }
8780 if (itemQBIndex != -1 && player)
8781 player.SetLoadedQuickBarItemBind(this,itemQBIndex);
8782 }
8783 }
8784
8785 if (version < 140)
8786 {
8787 // variable management system
8788 if (!LoadVariables(ctx, version))
8789 {
8790 m_IsStoreLoad = false;
8791 return false;
8792 }
8793 }
8794
8795 //agent trasmission system
8796 if (!LoadAgents(ctx, version))
8797 {
8798 m_IsStoreLoad = false;
8799 return false;
8800 }
8801 if (version >= 132)
8802 {
8803 RemotelyActivatedItemBehaviour raib = GetRemotelyActivatedItemBehaviour();
8804 if (raib)
8805 {
8806 if (!raib.OnStoreLoad(ctx,version))
8807 {
8808 m_IsStoreLoad = false;
8809 return false;
8810 }
8811 }
8812 }
8813
8814 m_IsStoreLoad = false;
8815 return true;
8816 }
8817
8818 //----------------------------------------------------------------
8819
8820 override void OnStoreSave(ParamsWriteContext ctx)
8821 {
8822 super.OnStoreSave(ctx);
8823
8824 PlayerBase player;
8825 if (PlayerBase.CastTo(player,GetHierarchyRootPlayer()))
8826 {
8827 ctx.Write(true); // Keep track of if we should actually read this in or not
8828 //Save quickbar item bind
8829 int itemQBIndex = -1;
8830 itemQBIndex = player.FindQuickBarEntityIndex(this);
8831 ctx.Write(itemQBIndex);
8832 }
8833 else
8834 {
8835 ctx.Write(false); // Keep track of if we should actually read this in or not
8836 }
8837
8838 SaveAgents(ctx);//agent trasmission system
8839
8840 RemotelyActivatedItemBehaviour raib = GetRemotelyActivatedItemBehaviour();
8841 if (raib)
8842 {
8843 raib.OnStoreSave(ctx);
8844 }
8845 }
8846 //----------------------------------------------------------------
8847
8848 override void AfterStoreLoad()
8849 {
8850 super.AfterStoreLoad();
8851
8853 {
8855 }
8856
8857 if (GetStoreLoadedQuantity() != float.LOWEST)
8858 {
8860 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
8861 }
8862 }
8863
8864 override void EEOnAfterLoad()
8865 {
8866 super.EEOnAfterLoad();
8867
8869 {
8870 m_FixDamageSystemInit = false;
8871 }
8872
8875 }
8876
8877 bool CanBeDisinfected()
8878 {
8879 return false;
8880 }
8881
8882
8883 //----------------------------------------------------------------
8884 override void OnVariablesSynchronized()
8885 {
8886 if (m_Initialized)
8887 {
8888 #ifdef PLATFORM_CONSOLE
8889 //bruteforce it is
8890 if (IsSplitable())
8891 {
8892 UIScriptedMenu menu = g_Game.GetUIManager().FindMenu(MENU_INVENTORY);
8893 if (menu)
8894 {
8895 menu.Refresh();
8896 }
8897 }
8898 #endif
8899 }
8900
8902 {
8903 PlayImpactSound(m_ConfigWeight, m_ImpactSpeed, m_ImpactSoundSurfaceHash);
8904 m_WantPlayImpactSound = false;
8905 }
8906
8908 {
8909 SetWeightDirty();
8911 }
8912 if (m_VarWet != m_VarWetPrev)
8913 {
8916 }
8917
8918 if (m_SoundSyncPlay != 0)
8919 {
8922
8923 m_SoundSyncPlay = 0;
8924 m_SoundSyncSlotID = -1;
8925 }
8926 if (m_SoundSyncStop != 0)
8927 {
8929 m_ItemSoundHandler.StopItemSoundClient(m_SoundSyncStop);
8930 m_SoundSyncStop = 0;
8931 }
8932
8933 super.OnVariablesSynchronized();
8934 }
8935
8936 //------------------------- Quantity
8937 //----------------------------------------------------------------
8939 override bool SetQuantity(float value, bool destroy_config = true, bool destroy_forced = false, bool allow_client = false, bool clamp_to_stack_max = true)
8940 {
8941 if (!IsServerCheck(allow_client))
8942 return false;
8943
8944 if (!HasQuantity())
8945 return false;
8946
8947 float min = GetQuantityMin();
8948 float max = GetQuantityMax();
8949
8950 if (value <= (min + 0.001))
8951 value = min;
8952
8953 if (value == min)
8954 {
8955 if (destroy_config)
8956 {
8957 bool dstr = ConfigGetBool("varQuantityDestroyOnMin");
8958 if (dstr)
8959 {
8960 m_VarQuantity = Math.Clamp(value, min, max);
8961 this.Delete();
8962 return true;
8963 }
8964 }
8965 else if (destroy_forced)
8966 {
8967 m_VarQuantity = Math.Clamp(value, min, max);
8968 this.Delete();
8969 return true;
8970 }
8971 // we get here if destroy_config IS true AND dstr(config destroy param) IS false;
8972 RemoveAllAgents();//we remove all agents when we got to the min value, but the item is not getting deleted
8973 }
8974
8975 float delta = m_VarQuantity;
8976 m_VarQuantity = Math.Clamp(value, min, max);
8977
8978 if (g_Game.IsServer() || !g_Game.IsMultiplayer()) // single player or server side multiplayer
8979 {
8980 EntityAI parent = GetHierarchyRoot();
8981 InventoryLocation iLoc = new InventoryLocation();
8982 GetInventory().GetCurrentInventoryLocation(iLoc);
8983 if (iLoc && iLoc.IsValid() && delta != m_VarQuantity)
8984 {
8985 int iLocSlot = iLoc.GetSlot();
8986 if (delta < m_VarQuantity && iLoc.GetType() != InventoryLocationType.GROUND)
8987 {
8988 StartItemSoundServer(SoundConstants.ITEM_ATTACH, iLocSlot);
8989 }
8990 if (delta > m_VarQuantity && m_VarQuantity != 0 && !IsPrepareToDelete() && iLoc.GetType() == InventoryLocationType.ATTACHMENT)
8991 {
8992 StartItemSoundServer(SoundConstants.ITEM_DETACH, iLocSlot);
8993 }
8994 }
8995 }
8996
8997 if (GetStoreLoadedQuantity() == float.LOWEST)//any other value means we are setting quantity from storage
8998 {
8999 delta = m_VarQuantity - delta;
9000
9001 if (delta)
9002 OnQuantityChanged(delta);
9003 }
9004
9005 SetVariableMask(VARIABLE_QUANTITY);
9006
9007 return false;
9008 }
9009
9010 //----------------------------------------------------------------
9012 bool AddQuantity(float value, bool destroy_config = true, bool destroy_forced = false)
9013 {
9014 return SetQuantity(GetQuantity() + value, destroy_config, destroy_forced);
9015 }
9016 //----------------------------------------------------------------
9017 void SetQuantityMax()
9018 {
9019 float max = GetQuantityMax();
9020 SetQuantity(max);
9021 }
9022
9023 override void SetQuantityToMinimum()
9024 {
9025 float min = GetQuantityMin();
9026 SetQuantity(min);
9027 }
9028 //----------------------------------------------------------------
9030 override void SetQuantityNormalized(float value, bool destroy_config = true, bool destroy_forced = false)
9031 {
9032 float value_clamped = Math.Clamp(value, 0, 1);//just to make sure
9033 int result = Math.Round(Math.Lerp(GetQuantityMin(), GetQuantityMax(), value_clamped));
9034 SetQuantity(result, destroy_config, destroy_forced);
9035 }
9036
9037 //----------------------------------------------------------------
9039 override float GetQuantityNormalized()
9040 {
9041 return Math.InverseLerp(GetQuantityMin(), GetQuantityMax(),m_VarQuantity);
9042 }
9043
9045 {
9046 return GetQuantityNormalized();
9047 }
9048
9049 /*void SetAmmoNormalized(float value)
9050 {
9051 float value_clamped = Math.Clamp(value, 0, 1);
9052 Magazine this_mag = Magazine.Cast(this);
9053 int max_rounds = this_mag.GetAmmoMax();
9054 int result = value * max_rounds;//can the rounded if higher precision is required
9055 this_mag.SetAmmoCount(result);
9056 }*/
9057 //----------------------------------------------------------------
9058 override int GetQuantityMax()
9059 {
9060 int slot = -1;
9061 GameInventory inventory = GetInventory();
9062 if (inventory)
9063 {
9064 InventoryLocation il = new InventoryLocation;
9065 inventory.GetCurrentInventoryLocation(il);
9066 slot = il.GetSlot();
9067 }
9068
9069 return GetTargetQuantityMax(slot);
9070 }
9071
9072 override int GetTargetQuantityMax(int attSlotID = -1)
9073 {
9074 float quantity_max = 0;
9075
9076 if (IsSplitable()) //only stackable/splitable items can check for stack size
9077 {
9078 if (attSlotID != -1)
9079 quantity_max = InventorySlots.GetStackMaxForSlotId(attSlotID);
9080
9081 if (quantity_max <= 0)
9082 quantity_max = m_VarStackMax;
9083 }
9084
9085 if (quantity_max <= 0)
9086 quantity_max = m_VarQuantityMax;
9087
9088 return quantity_max;
9089 }
9090 //----------------------------------------------------------------
9091 override int GetQuantityMin()
9092 {
9093 return m_VarQuantityMin;
9094 }
9095 //----------------------------------------------------------------
9096 int GetQuantityInit()
9097 {
9098 return m_VarQuantityInit;
9099 }
9100
9101 //----------------------------------------------------------------
9102 override bool HasQuantity()
9103 {
9104 return !(GetQuantityMax() - GetQuantityMin() == 0);
9105 }
9106
9107 override float GetQuantity()
9108 {
9109 return m_VarQuantity;
9110 }
9111
9112 bool IsFullQuantity()
9113 {
9114 return GetQuantity() >= GetQuantityMax();
9115 }
9116
9117 //Calculates weight of single item without attachments and cargo
9118 override float GetSingleInventoryItemWeightEx()
9119 {
9120 //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
9121 float weightEx = GetWeightEx();//overall weight of the item
9122 float special = GetInventoryAndCargoWeight();//cargo and attachment weight
9123 return weightEx - special;
9124 }
9125
9126 // Obsolete, use GetSingleInventoryItemWeightEx() instead
9128 {
9130 }
9131
9132 override protected float GetWeightSpecialized(bool forceRecalc = false)
9133 {
9134 if (IsSplitable()) //quantity determines size of the stack
9135 {
9136 #ifdef DEVELOPER
9137 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
9138 {
9139 WeightDebugData data1 = WeightDebug.GetWeightDebug(this);
9140 data1.SetCalcDetails("TIB1: " + GetConfigWeightModifiedDebugText() +" * " + GetQuantity()+"(quantity)");
9141 }
9142 #endif
9143
9144 return GetQuantity() * GetConfigWeightModified();
9145 }
9146 else if (HasEnergyManager())// items with energy manager
9147 {
9148 #ifdef DEVELOPER
9149 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
9150 {
9151 WeightDebugData data2 = WeightDebug.GetWeightDebug(this);
9152 data2.SetCalcDetails("TIB2: "+super.GetWeightSpecialized(forceRecalc)+"(contents weight) + " + GetConfigWeightModifiedDebugText() +" + " + GetCompEM().GetEnergy()+"(energy) * " + ConfigGetFloat("weightPerQuantityUnit") +"(weightPerQuantityUnit)");
9153 }
9154 #endif
9155 return super.GetWeightSpecialized(forceRecalc) + (GetCompEM().GetEnergy() * ConfigGetFloat("weightPerQuantityUnit")) + GetConfigWeightModified();
9156 }
9157 else//everything else
9158 {
9159 #ifdef DEVELOPER
9160 if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
9161 {
9162 WeightDebugData data3 = WeightDebug.GetWeightDebug(this);
9163 data3.SetCalcDetails("TIB3: "+super.GetWeightSpecialized(forceRecalc)+"(contents weight) + " + GetConfigWeightModifiedDebugText() +" + " + GetQuantity()+"(quantity) * " + ConfigGetFloat("weightPerQuantityUnit") +"(weightPerQuantityUnit))");
9164 }
9165 #endif
9166 return super.GetWeightSpecialized(forceRecalc) + (GetQuantity() * ConfigGetFloat("weightPerQuantityUnit")) + GetConfigWeightModified();
9167 }
9168 }
9169
9171 int GetNumberOfItems()
9172 {
9173 int item_count = 0;
9174 ItemBase item;
9175
9176 GameInventory inventory = GetInventory();
9177 CargoBase cargo = inventory.GetCargo();
9178 if (cargo != NULL)
9179 {
9180 item_count = cargo.GetItemCount();
9181 }
9182
9183 int nAttachments = inventory.AttachmentCount();
9184 for (int i = 0; i < nAttachments; ++i)
9185 {
9186 Class.CastTo(item, inventory.GetAttachmentFromIndex(i));
9187 if (item)
9188 item_count += item.GetNumberOfItems();
9189 }
9190 return item_count;
9191 }
9192
9194 float GetUnitWeight(bool include_wetness = true)
9195 {
9196 float weight = 0;
9197 float wetness = 1;
9198 if (include_wetness)
9199 wetness += GetWet();
9200 if (IsSplitable()) //quantity determines size of the stack
9201 {
9202 weight = wetness * m_ConfigWeight;
9203 }
9204 else if (IsLiquidContainer()) //is a liquid container, default liquid weight is set to 1. May revisit later?
9205 {
9206 weight = 1;
9207 }
9208 return weight;
9209 }
9210
9211 //-----------------------------------------------------------------
9212
9213 override void ClearInventory()
9214 {
9215 GameInventory inventory = GetInventory();
9216 if ((g_Game.IsServer() || !g_Game.IsMultiplayer()) && inventory)
9217 {
9218 array<EntityAI> items = new array<EntityAI>;
9219 inventory.EnumerateInventory(InventoryTraversalType.INORDER, items);
9220 for (int i = 0; i < items.Count(); ++i)
9221 {
9222 ItemBase item = ItemBase.Cast(items.Get(i));
9223 if (item)
9224 {
9225 g_Game.ObjectDelete(item);
9226 }
9227 }
9228 }
9229 }
9230
9231 //------------------------- Energy
9232
9233 //----------------------------------------------------------------
9234 float GetEnergy()
9235 {
9236 float energy = 0;
9237 if (HasEnergyManager())
9238 {
9239 energy = GetCompEM().GetEnergy();
9240 }
9241 return energy;
9242 }
9243
9244
9245 override void OnEnergyConsumed()
9246 {
9247 super.OnEnergyConsumed();
9248
9250 }
9251
9252 override void OnEnergyAdded()
9253 {
9254 super.OnEnergyAdded();
9255
9257 }
9258
9259 // Converts energy (from Energy Manager) to quantity, if enabled.
9261 {
9262 if (g_Game.IsServer() && HasEnergyManager() && GetCompEM().HasConversionOfEnergyToQuantity())
9263 {
9264 if (HasQuantity())
9265 {
9266 float energy_0to1 = GetCompEM().GetEnergy0To1();
9267 SetQuantityNormalized(energy_0to1);
9268 }
9269 }
9270 }
9271
9272 //----------------------------------------------------------------
9273 float GetHeatIsolationInit()
9274 {
9275 return ConfigGetFloat("heatIsolation");
9276 }
9277
9278 float GetHeatIsolation()
9279 {
9280 return m_HeatIsolation;
9281 }
9282
9283 float GetDryingIncrement(string pIncrementName)
9284 {
9285 string paramPath = string.Format("CfgVehicles %1 EnvironmentWetnessIncrements Drying %2", GetType(), pIncrementName);
9286 if (g_Game.ConfigIsExisting(paramPath))
9287 return g_Game.ConfigGetFloat(paramPath);
9288
9289 return 0.0;
9290 }
9291
9292 float GetSoakingIncrement(string pIncrementName)
9293 {
9294 string paramPath = string.Format("CfgVehicles %1 EnvironmentWetnessIncrements Soaking %2", GetType(), pIncrementName);
9295 if (g_Game.ConfigIsExisting(paramPath))
9296 return g_Game.ConfigGetFloat(paramPath);
9297
9298 return 0.0;
9299 }
9300 //----------------------------------------------------------------
9301 override void SetWet(float value, bool allow_client = false)
9302 {
9303 if (!IsServerCheck(allow_client))
9304 return;
9305
9306 float min = GetWetMin();
9307 float max = GetWetMax();
9308
9309 float previousValue = m_VarWet;
9310
9311 m_VarWet = Math.Clamp(value, min, max);
9312
9313 if (previousValue != m_VarWet)
9314 {
9315 SetVariableMask(VARIABLE_WET);
9316 OnWetChanged(m_VarWet, previousValue);
9317 }
9318 }
9319 //----------------------------------------------------------------
9320 override void AddWet(float value)
9321 {
9322 SetWet(GetWet() + value);
9323 }
9324 //----------------------------------------------------------------
9325 override void SetWetMax()
9326 {
9328 }
9329 //----------------------------------------------------------------
9330 override float GetWet()
9331 {
9332 return m_VarWet;
9333 }
9334 //----------------------------------------------------------------
9335 override float GetWetMax()
9336 {
9337 return m_VarWetMax;
9338 }
9339 //----------------------------------------------------------------
9340 override float GetWetMin()
9341 {
9342 return m_VarWetMin;
9343 }
9344 //----------------------------------------------------------------
9345 override float GetWetInit()
9346 {
9347 return m_VarWetInit;
9348 }
9349 //----------------------------------------------------------------
9350 override void OnWetChanged(float newVal, float oldVal)
9351 {
9352 EWetnessLevel newLevel = GetWetLevelInternal(newVal);
9353 EWetnessLevel oldLevel = GetWetLevelInternal(oldVal);
9354 if (newLevel != oldLevel)
9355 {
9356 OnWetLevelChanged(newLevel,oldLevel);
9357 }
9358 }
9359
9360 override void OnWetLevelChanged(EWetnessLevel newLevel, EWetnessLevel oldLevel)
9361 {
9362 SetWeightDirty();
9363 }
9364
9365 override EWetnessLevel GetWetLevel()
9366 {
9367 return GetWetLevelInternal(m_VarWet);
9368 }
9369
9370 //----------------------------------------------------------------
9371
9372 override void SetStoreLoad(bool value)
9373 {
9374 m_IsStoreLoad = value;
9375 }
9376
9377 override bool IsStoreLoad()
9378 {
9379 return m_IsStoreLoad;
9380 }
9381
9382 override void SetStoreLoadedQuantity(float value)
9383 {
9384 m_StoreLoadedQuantity = value;
9385 }
9386
9387 override float GetStoreLoadedQuantity()
9388 {
9389 return m_StoreLoadedQuantity;
9390 }
9391
9392 //----------------------------------------------------------------
9393
9394 float GetItemModelLength()
9395 {
9396 if (ConfigIsExisting("itemModelLength"))
9397 {
9398 return ConfigGetFloat("itemModelLength");
9399 }
9400 return 0;
9401 }
9402
9403 float GetItemAttachOffset()
9404 {
9405 if (ConfigIsExisting("itemAttachOffset"))
9406 {
9407 return ConfigGetFloat("itemAttachOffset");
9408 }
9409 return 0;
9410 }
9411
9412 override void SetCleanness(int value, bool allow_client = false)
9413 {
9414 if (!IsServerCheck(allow_client))
9415 return;
9416
9417 int previousValue = m_Cleanness;
9418
9419 m_Cleanness = Math.Clamp(value, m_CleannessMin, m_CleannessMax);
9420
9421 if (previousValue != m_Cleanness)
9422 SetVariableMask(VARIABLE_CLEANNESS);
9423 }
9424
9425 override int GetCleanness()
9426 {
9427 return m_Cleanness;
9428 }
9429
9431 {
9432 return true;
9433 }
9434
9435 //----------------------------------------------------------------
9436 // ATTACHMENT LOCKING
9437 // Getters relevant to generic ActionLockAttachment
9438 int GetLockType()
9439 {
9440 return m_LockType;
9441 }
9442
9443 string GetLockSoundSet()
9444 {
9445 return m_LockSoundSet;
9446 }
9447
9448 //----------------------------------------------------------------
9449 //------------------------- Color
9450 // sets items color variable given color components
9451 override void SetColor(int r, int g, int b, int a)
9452 {
9457 SetVariableMask(VARIABLE_COLOR);
9458 }
9460 override void GetColor(out int r,out int g,out int b,out int a)
9461 {
9466 }
9467
9468 bool IsColorSet()
9469 {
9470 return IsVariableSet(VARIABLE_COLOR);
9471 }
9472
9474 string GetColorString()
9475 {
9476 int r,g,b,a;
9477 GetColor(r,g,b,a);
9478 r = r/255;
9479 g = g/255;
9480 b = b/255;
9481 a = a/255;
9482 return MiscGameplayFunctions.GetColorString(r, g, b, a);
9483 }
9484 //----------------------------------------------------------------
9485 //------------------------- LiquidType
9486
9487 override void SetLiquidType(int value, bool allow_client = false)
9488 {
9489 if (!IsServerCheck(allow_client))
9490 return;
9491
9492 int old = m_VarLiquidType;
9493 m_VarLiquidType = value;
9494 OnLiquidTypeChanged(old,value);
9495 SetVariableMask(VARIABLE_LIQUIDTYPE);
9496 }
9497
9498 int GetLiquidTypeInit()
9499 {
9500 return ConfigGetInt("varLiquidTypeInit");
9501 }
9502
9503 override int GetLiquidType()
9504 {
9505 return m_VarLiquidType;
9506 }
9507
9508 protected void OnLiquidTypeChanged(int oldType, int newType)
9509 {
9510 if (newType == LIQUID_NONE && GetIsFrozen())
9511 SetFrozen(false);
9512 }
9513
9515 void UpdateQuickbarShortcutVisibility(PlayerBase player)
9516 {
9517 player.SetEnableQuickBarEntityShortcut(this,!GetHierarchyParent() || GetHierarchyParent().GetInventory().AreChildrenAccessible());
9518 }
9519
9520 // -------------------------------------------------------------------------
9522 void OnInventoryEnter(Man player)
9523 {
9524 PlayerBase nplayer;
9525 if (PlayerBase.CastTo(nplayer, player))
9526 {
9527 m_CanPlayImpactSound = true;
9528 nplayer.SetEnableQuickBarEntityShortcut(this,!GetHierarchyParent() || GetHierarchyParent().GetInventory().AreChildrenAccessible());
9529 }
9530 }
9531
9532 // -------------------------------------------------------------------------
9534 void OnInventoryExit(Man player)
9535 {
9536 PlayerBase nplayer;
9537 if (PlayerBase.CastTo(nplayer,player))
9538 {
9539 nplayer.SetEnableQuickBarEntityShortcut(this, false);
9540 }
9541
9542 player.GetHumanInventory().ClearUserReservedLocationForContainer(this);
9543
9544 if (HasEnergyManager())
9545 {
9546 GetCompEM().UpdatePlugState(); // Unplug the el. device if it's necesarry.
9547 }
9548 }
9549
9550 // ADVANCED PLACEMENT EVENTS
9551 override void OnPlacementStarted(Man player)
9552 {
9553 super.OnPlacementStarted(player);
9554
9555 SetTakeable(false);
9556 }
9557
9558 override void OnPlacementComplete(Man player, vector position = "0 0 0", vector orientation = "0 0 0")
9559 {
9560 if (m_AdminLog)
9561 {
9562 m_AdminLog.OnPlacementComplete(player, this);
9563 }
9564
9565 super.OnPlacementComplete(player, position, orientation);
9566 }
9567
9568 //-----------------------------
9569 // AGENT SYSTEM
9570 //-----------------------------
9571 //--------------------------------------------------------------------------
9572 bool ContainsAgent(int agent_id)
9573 {
9574 if (agent_id & m_AttachedAgents)
9575 {
9576 return true;
9577 }
9578 else
9579 {
9580 return false;
9581 }
9582 }
9583
9584 //--------------------------------------------------------------------------
9585 override void RemoveAgent(int agent_id)
9586 {
9587 if (ContainsAgent(agent_id))
9588 {
9589 m_AttachedAgents = ~agent_id & m_AttachedAgents;
9590 }
9591 }
9592
9593 //--------------------------------------------------------------------------
9594 override void RemoveAllAgents()
9595 {
9596 m_AttachedAgents = 0;
9597 }
9598 //--------------------------------------------------------------------------
9599 override void RemoveAllAgentsExcept(int agent_to_keep)
9600 {
9601 m_AttachedAgents = m_AttachedAgents & agent_to_keep;
9602 }
9603 // -------------------------------------------------------------------------
9604 override void InsertAgent(int agent, float count = 1)
9605 {
9606 if (count < 1)
9607 return;
9608 //Debug.Log("Inserting Agent on item: " + agent.ToString() +" count: " + count.ToString());
9610 }
9611
9613 void TransferAgents(int agents)
9614 {
9616 }
9617
9618 // -------------------------------------------------------------------------
9619 override int GetAgents()
9620 {
9621 return m_AttachedAgents;
9622 }
9623 //----------------------------------------------------------------------
9624
9625 /*int GetContaminationType()
9626 {
9627 int contamination_type;
9628
9629 const int CONTAMINATED_MASK = eAgents.CHOLERA | eAgents.INFLUENZA | eAgents.SALMONELLA | eAgents.BRAIN;
9630 const int POISONED_MASK = eAgents.FOOD_POISON | eAgents.CHEMICAL_POISON;
9631 const int NERVE_GAS_MASK = eAgents.CHEMICAL_POISON;
9632 const int DIRTY_MASK = eAgents.WOUND_AGENT;
9633
9634 Edible_Base edible = Edible_Base.Cast(this);
9635 int agents = GetAgents();
9636 if (edible)
9637 {
9638 NutritionalProfile profile = Edible_Base.GetNutritionalProfile(edible);
9639 if (profile)
9640 {
9641 agents = agents | profile.GetAgents();//merge item's agents with nutritional agents
9642 }
9643 }
9644 if (agents & CONTAMINATED_MASK)
9645 {
9646 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_CONTAMINATED;
9647 }
9648 if (agents & POISONED_MASK)
9649 {
9650 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_POISONED;
9651 }
9652 if (agents & NERVE_GAS_MASK)
9653 {
9654 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_NERVE_GAS;
9655 }
9656 if (agents & DIRTY_MASK)
9657 {
9658 contamination_type = contamination_type | EContaminationTypes.ITEM_BADGE_DIRTY;
9659 }
9660
9661 return agents;
9662 }*/
9663
9664 // -------------------------------------------------------------------------
9665 bool LoadAgents(ParamsReadContext ctx, int version)
9666 {
9667 if (!ctx.Read(m_AttachedAgents))
9668 return false;
9669 return true;
9670 }
9671 // -------------------------------------------------------------------------
9673 {
9674
9676 }
9677 // -------------------------------------------------------------------------
9678
9680 override void CheckForRoofLimited(float timeTresholdMS = 3000)
9681 {
9682 super.CheckForRoofLimited(timeTresholdMS);
9683
9684 float time = g_Game.GetTime();
9685 if ((time - m_PreviousRoofTestTime) >= timeTresholdMS)
9686 {
9687 m_PreviousRoofTestTime = time;
9688 SetRoofAbove(MiscGameplayFunctions.IsUnderRoof(this));
9689 }
9690 }
9691
9692 // returns item's protection level against enviromental hazard, for masks with filters, returns the filters protection for valid filter, otherwise 0
9693 float GetProtectionLevel(int type, bool consider_filter = false, int system = 0)
9694 {
9695 if (IsDamageDestroyed() || (HasQuantity() && GetQuantity() <= 0))
9696 {
9697 return 0;
9698 }
9699
9700 if (GetInventory().GetAttachmentSlotsCount() != 0)//is it an item with attachable filter ?
9701 {
9702 ItemBase filter = ItemBase.Cast(FindAttachmentBySlotName("GasMaskFilter"));
9703 if (filter)
9704 return filter.GetProtectionLevel(type, false, system);//it's a valid filter, return the protection
9705 else
9706 return 0;//otherwise return 0 when no filter attached
9707 }
9708
9709 string subclassPath, entryName;
9710
9711 switch (type)
9712 {
9713 case DEF_BIOLOGICAL:
9714 entryName = "biological";
9715 break;
9716 case DEF_CHEMICAL:
9717 entryName = "chemical";
9718 break;
9719 default:
9720 entryName = "biological";
9721 break;
9722 }
9723
9724 subclassPath = "CfgVehicles " + this.GetType() + " Protection ";
9725
9726 return g_Game.ConfigGetFloat(subclassPath + entryName);
9727 }
9728
9729
9730
9732 override void EEOnCECreate()
9733 {
9734 if (!IsMagazine())
9736
9738 }
9739
9740
9741 //-------------------------
9742 // OPEN/CLOSE USER ACTIONS
9743 //-------------------------
9745 void Open();
9746 void Close();
9747 bool IsOpen()
9748 {
9749 return true;
9750 }
9751
9752 override bool CanDisplayCargo()
9753 {
9754 return IsOpen();
9755 }
9756
9757
9758 // ------------------------------------------------------------
9759 // CONDITIONS
9760 // ------------------------------------------------------------
9761 override bool CanPutInCargo(EntityAI parent)
9762 {
9763 if (parent)
9764 {
9765 if (parent.IsInherited(DayZInfected))
9766 return true;
9767
9768 if (!parent.IsRuined())
9769 return true;
9770 }
9771
9772 return true;
9773 }
9774
9775 override bool CanPutAsAttachment(EntityAI parent)
9776 {
9777 if (!super.CanPutAsAttachment(parent))
9778 {
9779 return false;
9780 }
9781
9782 if (!IsRuined() && !parent.IsRuined())
9783 {
9784 return true;
9785 }
9786
9787 return false;
9788 }
9789
9790 override bool CanReceiveItemIntoCargo(EntityAI item)
9791 {
9792 //removed 15.06. coz of loading from storage -> after load items in cargo was lost -> waiting for proper solution
9793 //if (GetHealthLevel() == GameConstants.STATE_RUINED)
9794 // return false;
9795
9796 return super.CanReceiveItemIntoCargo(item);
9797 }
9798
9799 override bool CanReceiveAttachment(EntityAI attachment, int slotId)
9800 {
9801 //removed 15.06. coz of loading from storage -> after load items in cargo was lost -> waiting for proper solution
9802 //if (GetHealthLevel() == GameConstants.STATE_RUINED)
9803 // return false;
9804
9805 GameInventory attachmentInv = attachment.GetInventory();
9806 if (attachmentInv && attachmentInv.GetCargo() && attachmentInv.GetCargo().GetItemCount() > 0)
9807 {
9808 if (GetHierarchyParent() && !GetHierarchyParent().IsInherited(PlayerBase))
9809 return false;
9810 }
9811
9812 InventoryLocation loc = new InventoryLocation();
9813 attachment.GetInventory().GetCurrentInventoryLocation(loc);
9814 if (loc && loc.IsValid() && !GetInventory().AreChildrenAccessible())
9815 return false;
9816
9817 return super.CanReceiveAttachment(attachment, slotId);
9818 }
9819
9820 override bool CanReleaseAttachment(EntityAI attachment)
9821 {
9822 if (!super.CanReleaseAttachment(attachment))
9823 return false;
9824
9825 return GetInventory().AreChildrenAccessible();
9826 }
9827
9828 /*override bool CanLoadAttachment(EntityAI attachment)
9829 {
9830 //removed 15.06. coz of loading from storage -> after load items in cargo was lost -> waiting for proper solution
9831 //if (GetHealthLevel() == GameConstants.STATE_RUINED)
9832 // return false;
9833
9834 GameInventory attachmentInv = attachment.GetInventory();
9835 if (attachmentInv && attachmentInv.GetCargo() && attachmentInv.GetCargo().GetItemCount() > 0)
9836 {
9837 bool boo = (GetHierarchyParent() && !GetHierarchyParent().IsInherited(PlayerBase));
9838 ErrorEx("CanLoadAttachment | this: " + this + " | attachment: " + attachment + " | boo: " + boo,ErrorExSeverity.INFO);
9839
9840 if (GetHierarchyParent() && !GetHierarchyParent().IsInherited(PlayerBase))
9841 return false;
9842 }
9843
9844 return super.CanLoadAttachment(attachment);
9845 }*/
9846
9847 // Plays muzzle flash particle effects
9848 static void PlayFireParticles(ItemBase weapon, int muzzle_index, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
9849 {
9850 int id = muzzle_owner.GetMuzzleID();
9851 array<ref WeaponParticlesOnFire> WPOF_array = m_OnFireEffect.Get(id);
9852
9853 if (WPOF_array)
9854 {
9855 for (int i = 0; i < WPOF_array.Count(); i++)
9856 {
9857 WeaponParticlesOnFire WPOF = WPOF_array.Get(i);
9858
9859 if (WPOF)
9860 {
9861 WPOF.OnActivate(weapon, muzzle_index, ammoType, muzzle_owner, suppressor, config_to_search);
9862 }
9863 }
9864 }
9865 }
9866
9867 // Plays bullet eject particle effects (usually just smoke, the bullet itself is a 3D model and is not part of this function)
9868 static void PlayBulletCasingEjectParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
9869 {
9870 int id = muzzle_owner.GetMuzzleID();
9871 array<ref WeaponParticlesOnBulletCasingEject> WPOBE_array = m_OnBulletCasingEjectEffect.Get(id);
9872
9873 if (WPOBE_array)
9874 {
9875 for (int i = 0; i < WPOBE_array.Count(); i++)
9876 {
9877 WeaponParticlesOnBulletCasingEject WPOBE = WPOBE_array.Get(i);
9878
9879 if (WPOBE)
9880 {
9881 WPOBE.OnActivate(weapon, 0, ammoType, muzzle_owner, suppressor, config_to_search);
9882 }
9883 }
9884 }
9885 }
9886
9887 // Plays all weapon overheating particles
9888 static void PlayOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
9889 {
9890 int id = muzzle_owner.GetMuzzleID();
9891 array<ref WeaponParticlesOnOverheating> WPOOH_array = weapon.m_OnOverheatingEffect.Get(id);
9892
9893 if (WPOOH_array)
9894 {
9895 for (int i = 0; i < WPOOH_array.Count(); i++)
9896 {
9897 WeaponParticlesOnOverheating WPOOH = WPOOH_array.Get(i);
9898
9899 if (WPOOH)
9900 {
9901 WPOOH.OnActivate(weapon, 0, ammoType, muzzle_owner, suppressor, config_to_search);
9902 }
9903 }
9904 }
9905 }
9906
9907 // Updates all weapon overheating particles
9908 static void UpdateOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
9909 {
9910 int id = muzzle_owner.GetMuzzleID();
9911 array<ref WeaponParticlesOnOverheating> WPOOH_array = weapon.m_OnOverheatingEffect.Get(id);
9912
9913 if (WPOOH_array)
9914 {
9915 for (int i = 0; i < WPOOH_array.Count(); i++)
9916 {
9917 WeaponParticlesOnOverheating WPOOH = WPOOH_array.Get(i);
9918
9919 if (WPOOH)
9920 {
9921 WPOOH.OnUpdate(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
9922 }
9923 }
9924 }
9925 }
9926
9927 // Stops overheating particles
9928 static void StopOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
9929 {
9930 int id = muzzle_owner.GetMuzzleID();
9931 array<ref WeaponParticlesOnOverheating> WPOOH_array = weapon.m_OnOverheatingEffect.Get(id);
9932
9933 if (WPOOH_array)
9934 {
9935 for (int i = 0; i < WPOOH_array.Count(); i++)
9936 {
9937 WeaponParticlesOnOverheating WPOOH = WPOOH_array.Get(i);
9938
9939 if (WPOOH)
9940 {
9941 WPOOH.OnDeactivate(weapon, ammoType, muzzle_owner, suppressor, config_to_search);
9942 }
9943 }
9944 }
9945 }
9946
9947 //----------------------------------------------------------------
9948 //Item Behaviour - unified approach
9949 override bool IsHeavyBehaviour()
9950 {
9951 if (m_ItemBehaviour == 0)
9952 {
9953 return true;
9954 }
9955
9956 return false;
9957 }
9958
9959 override bool IsOneHandedBehaviour()
9960 {
9961 if (m_ItemBehaviour == 1)
9962 {
9963 return true;
9964 }
9965
9966 return false;
9967 }
9968
9969 override bool IsTwoHandedBehaviour()
9970 {
9971 if (m_ItemBehaviour == 2)
9972 {
9973 return true;
9974 }
9975
9976 return false;
9977 }
9978
9979 bool IsDeployable()
9980 {
9981 return false;
9982 }
9983
9985 float GetDeployTime()
9986 {
9987 return UATimeSpent.DEFAULT_DEPLOY;
9988 }
9989
9990
9991 //----------------------------------------------------------------
9992 // Item Targeting (User Actions)
9993 override void SetTakeable(bool pState)
9994 {
9995 m_IsTakeable = pState;
9996 SetSynchDirty();
9997 }
9998
9999 override bool IsTakeable()
10000 {
10001 return m_IsTakeable;
10002 }
10003
10004 // For cases where we want to show object widget which cant be taken to hands
10006 {
10007 return false;
10008 }
10009
10011 protected void PreLoadSoundAttachmentType()
10012 {
10013 string att_type = "None";
10014
10015 if (ConfigIsExisting("soundAttType"))
10016 {
10017 att_type = ConfigGetString("soundAttType");
10018 }
10019
10020 m_SoundAttType = att_type;
10021 }
10022
10023 override string GetAttachmentSoundType()
10024 {
10025 return m_SoundAttType;
10026 }
10027
10028 //----------------------------------------------------------------
10029 //SOUNDS - ItemSoundHandler
10030 //----------------------------------------------------------------
10031
10032 string GetPlaceSoundset(); // played when deploy starts
10033 string GetLoopDeploySoundset(); // played when deploy starts and stopped when it finishes
10034 string GetDeploySoundset(); // played when deploy sucessfully finishes
10035 string GetLoopFoldSoundset(); // played when fold starts and stopped when it finishes
10036 string GetFoldSoundset(); // played when fold sucessfully finishes
10037
10039 {
10040 if (!m_ItemSoundHandler)
10042
10043 return m_ItemSoundHandler;
10044 }
10045
10046 // override to initialize sounds
10047 protected void InitItemSounds()
10048 {
10049 if (GetPlaceSoundset() == string.Empty && GetDeploySoundset() == string.Empty && GetLoopDeploySoundset() == string.Empty && !GetInventoryItemType().SetDetachSoundEvent() && !GetInventoryItemType().SetAttachSoundEvent())
10050 return;
10051
10053
10054 if (GetPlaceSoundset() != string.Empty)
10055 handler.AddSound(SoundConstants.ITEM_PLACE, GetPlaceSoundset());
10056
10057 if (GetDeploySoundset() != string.Empty)
10058 handler.AddSound(SoundConstants.ITEM_DEPLOY, GetDeploySoundset());
10059
10060 SoundParameters params = new SoundParameters();
10061 params.m_Loop = true;
10062 if (GetLoopDeploySoundset() != string.Empty)
10063 handler.AddSound(SoundConstants.ITEM_DEPLOY_LOOP, GetLoopDeploySoundset(), params);
10064 }
10065
10066 // Start sound using ItemSoundHandler
10067 void StartItemSoundServer(int id, int slotId)
10068 {
10069 if (g_Game.IsServer() || !g_Game.IsMultiplayer()) // single player or server side multiplayer
10070 {
10071 m_SoundSyncSlotID = slotId;
10072 m_SoundSyncPlay = id;
10073
10074 SetSynchDirty();
10075
10076 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).Remove(ClearStartItemSoundServer); // in case one is queued already
10077 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(ClearStartItemSoundServer, 100);
10078 }
10079 }
10080
10081 void StartItemSoundServer(int id)
10082 {
10083 StartItemSoundServer(id, InventorySlots.INVALID);
10084 }
10085
10086 // Stop sound using ItemSoundHandler
10087 void StopItemSoundServer(int id)
10088 {
10089 if (!g_Game.IsServer())
10090 return;
10091
10092 m_SoundSyncStop = id;
10093 SetSynchDirty();
10094
10095 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).Remove(ClearStopItemSoundServer); // in case one is queued already
10096 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(ClearStopItemSoundServer, 100);
10097 }
10098
10099 protected void ClearStartItemSoundServer()
10100 {
10101 m_SoundSyncPlay = 0;
10102 m_SoundSyncSlotID = InventorySlots.INVALID;
10103 }
10104
10105 protected void ClearStopItemSoundServer()
10106 {
10107 m_SoundSyncStop = 0;
10108 }
10109
10110 void OnApply(PlayerBase player);
10111
10113 {
10114 return 1.0;
10115 };
10116 //returns applicable selection
10117 array<string> GetHeadHidingSelection()
10118 {
10120 }
10121
10123 {
10125 }
10126
10127 WrittenNoteData GetWrittenNoteData() {};
10128
10130 {
10131 SetDynamicPhysicsLifeTime(0.01);
10132 m_ItemBeingDroppedPhys = false;
10133 }
10134
10136 {
10137 array<string> zone_names = new array<string>;
10138 GetDamageZones(zone_names);
10139 for (int i = 0; i < zone_names.Count(); i++)
10140 {
10141 SetHealthMax(zone_names.Get(i),"Health");
10142 }
10143 SetHealthMax("","Health");
10144 }
10145
10147 void SetZoneDamageCEInit()
10148 {
10149 float global_health = GetHealth01("","Health");
10150 array<string> zones = new array<string>;
10151 GetDamageZones(zones);
10152 //set damage of all zones to match global health level
10153 for (int i = 0; i < zones.Count(); i++)
10154 {
10155 SetHealth01(zones.Get(i),"Health",global_health);
10156 }
10157 }
10158
10160 bool IsCoverFaceForShave(string slot_name)
10161 {
10162 return IsExclusionFlagPresent(PlayerBase.GetFaceCoverageShaveValues());
10163 }
10164
10165 void ProcessItemWetness(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
10166 {
10167 if (!hasRootAsPlayer)
10168 {
10169 if (refParentIB)
10170 {
10171 // parent is wet
10172 if ((refParentIB.GetWet() >= GameConstants.STATE_SOAKING_WET) && (m_VarWet < m_VarWetMax))
10173 AddWet(delta * GameConstants.WETNESS_RATE_WETTING_INSIDE);
10174 // parent has liquid inside
10175 else if ((refParentIB.GetLiquidType() != 0) && (refParentIB.GetQuantity() > 0) && (m_VarWet < m_VarWetMax))
10176 AddWet(delta * GameConstants.WETNESS_RATE_WETTING_LIQUID);
10177 // drying
10178 else if (m_VarWet > m_VarWetMin)
10179 AddWet(-1 * delta * GetDryingIncrement("ground") * 2);
10180 }
10181 else
10182 {
10183 // drying on ground or inside non-itembase (car, ...)
10184 if (m_VarWet > m_VarWetMin)
10185 AddWet(-1 * delta * GetDryingIncrement("ground"));
10186 }
10187 }
10188 }
10189
10190 void ProcessItemTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
10191 {
10193 {
10194 float target = g_Game.GetMission().GetWorldData().GetBaseEnvTemperatureAtObject(this);
10195 if (GetTemperature() != target || !IsFreezeThawProgressFinished())
10196 {
10197 float heatPermCoef = 1.0;
10198 EntityAI ent = this;
10199 while (ent)
10200 {
10201 heatPermCoef *= ent.GetHeatPermeabilityCoef();
10202 ent = ent.GetHierarchyParent();
10203 }
10204
10205 SetTemperatureEx(new TemperatureDataInterpolated(target,ETemperatureAccessTypes.ACCESS_WORLD,delta,GameConstants.TEMP_COEF_WORLD,heatPermCoef));
10206 }
10207 }
10208 }
10209
10210 void HierarchyCheck(out bool hasParent, out bool hasRootAsPlayer, out ItemBase refParentIB)
10211 {
10212 // hierarchy check for an item to decide whether it has some parent and it is in some player inventory
10213 EntityAI parent = GetHierarchyParent();
10214 if (!parent)
10215 {
10216 hasParent = false;
10217 hasRootAsPlayer = false;
10218 }
10219 else
10220 {
10221 hasParent = true;
10222 hasRootAsPlayer = (GetHierarchyRootPlayer() != null);
10223 refParentIB = ItemBase.Cast(parent);
10224 }
10225 }
10226
10227 protected void ProcessDecay(float delta, bool hasRootAsPlayer)
10228 {
10229 // this is stub, implemented on Edible_Base
10230 }
10231
10232 bool CanDecay()
10233 {
10234 // return true used on selected food clases so they can decay
10235 return false;
10236 }
10237
10238 protected bool CanProcessDecay()
10239 {
10240 // this is stub, implemented on Edible_Base class
10241 // used to determine whether it is still necessary for the food to decay
10242 return false;
10243 }
10244
10245 protected bool CanHaveWetness()
10246 {
10247 // return true used on selected items that have a wetness effect
10248 return false;
10249 }
10250
10252 bool CanBeConsumed(ConsumeConditionData data = null)
10253 {
10254 return !GetIsFrozen() && IsOpen();
10255 }
10256
10257 override void ProcessVariables()
10258 {
10259 bool hasParent = false, hasRootAsPlayer = false;
10260 ItemBase refParentIB;
10261
10262 bool wwtu = g_Game.IsWorldWetTempUpdateEnabled();
10263 bool foodDecay = g_Game.IsFoodDecayEnabled();
10264
10265 if (wwtu || foodDecay)
10266 {
10267 bool processWetness = wwtu && CanHaveWetness();
10268 bool processTemperature = wwtu && CanHaveTemperature();
10269 bool processDecay = foodDecay && CanDecay() && CanProcessDecay();
10270
10271 if (processWetness || processTemperature || processDecay)
10272 {
10273 HierarchyCheck(hasParent, hasRootAsPlayer, refParentIB);
10274
10275 if (processWetness)
10276 ProcessItemWetness(m_ElapsedSinceLastUpdate, hasParent, hasRootAsPlayer, refParentIB);
10277
10278 if (processTemperature)
10279 ProcessItemTemperature(m_ElapsedSinceLastUpdate, hasParent, hasRootAsPlayer, refParentIB);
10280
10281 if (processDecay)
10282 ProcessDecay(m_ElapsedSinceLastUpdate, hasRootAsPlayer);
10283 }
10284 }
10285 }
10286
10289 {
10290 return m_TemperaturePerQuantityWeight * GameConstants.ITEM_TEMPERATURE_QUANTITY_WEIGHT_MULTIPLIER;
10291 }
10292
10293 override float GetTemperatureFreezeThreshold()
10294 {
10296 return Liquid.GetFreezeThreshold(GetLiquidType());
10297
10298 return super.GetTemperatureFreezeThreshold();
10299 }
10300
10301 override float GetTemperatureThawThreshold()
10302 {
10304 return Liquid.GetThawThreshold(GetLiquidType());
10305
10306 return super.GetTemperatureThawThreshold();
10307 }
10308
10309 override float GetItemOverheatThreshold()
10310 {
10312 return Liquid.GetBoilThreshold(GetLiquidType());
10313
10314 return super.GetItemOverheatThreshold();
10315 }
10316
10317 override float GetTemperatureFreezeTime()
10318 {
10319 if (HasQuantity())
10320 return Math.Lerp(GameConstants.TEMPERATURE_TIME_FREEZE_MIN,Math.Max(GameConstants.TEMPERATURE_TIME_FREEZE_MIN,super.GetTemperatureFreezeTime()),GetQuantityNormalized());
10321
10322 return super.GetTemperatureFreezeTime();
10323 }
10324
10325 override float GetTemperatureThawTime()
10326 {
10327 if (HasQuantity())
10328 return Math.Lerp(GameConstants.TEMPERATURE_TIME_THAW_MIN,Math.Max(GameConstants.TEMPERATURE_TIME_FREEZE_MIN,super.GetTemperatureThawTime()),GetQuantityNormalized());
10329
10330 return super.GetTemperatureThawTime();
10331 }
10332
10334 void AffectLiquidContainerOnFill(int liquid_type, float amount);
10336 void AffectLiquidContainerOnTransfer(int liquidType, float amount, float sourceLiquidTemperature);
10337
10338 bool IsCargoException4x3(EntityAI item)
10339 {
10340 return (item.IsKindOf("Cauldron") || item.IsKindOf("Pot") || item.IsKindOf("FryingPan") || item.IsKindOf("SmallProtectorCase") || (item.IsKindOf("PortableGasStove") && item.FindAttachmentBySlotName("CookingEquipment")));
10341 }
10342
10344 {
10345 MiscGameplayFunctions.TransferItemProperties(oldItem, this);
10346 }
10347
10349 void AddLightSourceItem(ItemBase lightsource)
10350 {
10351 m_LightSourceItem = lightsource;
10352 }
10353
10355 {
10356 m_LightSourceItem = null;
10357 }
10358
10360 {
10361 return m_LightSourceItem;
10362 }
10363
10365 array<int> GetValidFinishers()
10366 {
10367 return null;
10368 }
10369
10371 bool GetActionWidgetOverride(out typename name)
10372 {
10373 return false;
10374 }
10375
10376 bool PairWithDevice(notnull ItemBase otherDevice)
10377 {
10378 if (g_Game.IsServer())
10379 {
10380 ItemBase explosive = otherDevice;
10382 if (!trg)
10383 {
10384 trg = RemoteDetonatorTrigger.Cast(otherDevice);
10385 explosive = this;
10386 }
10387
10388 explosive.PairRemote(trg);
10389 trg.SetControlledDevice(explosive);
10390
10391 int persistentID = RemotelyActivatedItemBehaviour.GeneratePersistentID();
10392 trg.SetPersistentPairID(persistentID);
10393 explosive.SetPersistentPairID(persistentID);
10394
10395 return true;
10396 }
10397 return false;
10398 }
10399
10401 float GetBaitEffectivity()
10402 {
10403 float ret = 1.0;
10404 if (HasQuantity())
10405 ret *= GetQuantityNormalized();
10406 ret *= GetHealth01();
10407
10408 return ret;
10409 }
10410
10411 #ifdef DEVELOPER
10412 override void SetDebugItem()
10413 {
10414 super.SetDebugItem();
10415 _itemBase = this;
10416 }
10417
10418 override string GetDebugText()
10419 {
10420 string text = super.GetDebugText();
10421
10422 text += string.Format("Heat isolation(raw): %1\n", GetHeatIsolation());
10423 text += string.Format("Heat isolation(modified): %1\n", MiscGameplayFunctions.GetCurrentItemHeatIsolation(this));
10424
10425 return text;
10426 }
10427 #endif
10428
10429 bool CanBeUsedForSuicide()
10430 {
10431 return true;
10432 }
10433
10435 //DEPRECATED BELOW
10437 // Backwards compatibility
10438 void ProcessItemWetnessAndTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
10439 {
10440 ProcessItemWetness(delta, hasParent, hasRootAsPlayer, refParentIB);
10441 ProcessItemTemperature(delta, hasParent, hasRootAsPlayer, refParentIB);
10442 }
10443
10444 // replaced by ItemSoundHandler
10445 protected EffectSound m_SoundDeployFinish;
10446 protected EffectSound m_SoundPlace;
10447 protected EffectSound m_DeployLoopSoundEx;
10448 protected EffectSound m_SoundDeploy;
10449 bool m_IsPlaceSound;
10450 bool m_IsDeploySound;
10452
10453 string GetDeployFinishSoundset();
10454 void PlayDeploySound();
10455 void PlayDeployFinishSound();
10456 void PlayPlaceSound();
10457 void PlayDeployLoopSoundEx();
10458 void StopDeployLoopSoundEx();
10459 void SoundSynchRemoteReset();
10460 void SoundSynchRemote();
10461 bool UsesGlobalDeploy(){return false;}
10462 bool CanPlayDeployLoopSound(){return false;}
10464 bool IsPlaceSound(){return m_IsPlaceSound;}
10465 bool IsDeploySound(){return m_IsDeploySound;}
10466 void SetIsPlaceSound(bool is_place_sound);
10467 void SetIsDeploySound(bool is_deploy_sound);
10468
10469 [Obsolete("Use ItemSoundHandler instead")]
10471 void PlayAttachSound(string slot_type)
10472 {
10473 if (!g_Game.IsDedicatedServer())
10474 {
10475 if (ConfigIsExisting("attachSoundSet"))
10476 {
10477 string cfg_path = "";
10478 string soundset = "";
10479 string type_name = GetType();
10480
10481 TStringArray cfg_soundset_array = new TStringArray;
10482 TStringArray cfg_slot_array = new TStringArray;
10483 ConfigGetTextArray("attachSoundSet",cfg_soundset_array);
10484 ConfigGetTextArray("attachSoundSlot",cfg_slot_array);
10485
10486 if (cfg_soundset_array.Count() > 0 && cfg_soundset_array.Count() == cfg_slot_array.Count())
10487 {
10488 for (int i = 0; i < cfg_soundset_array.Count(); i++)
10489 {
10490 if (cfg_slot_array[i] == slot_type)
10491 {
10492 soundset = cfg_soundset_array[i];
10493 break;
10494 }
10495 }
10496 }
10497
10498 if (soundset != "")
10499 {
10500 EffectSound sound = SEffectManager.PlaySound(soundset, GetPosition());
10501 sound.SetAutodestroy(true);
10502 }
10503 }
10504 }
10505 }
10506
10507 void PlayDetachSound(string slot_type) {}
10508}
10509
10510EntityAI SpawnItemOnLocation(string object_name, notnull InventoryLocation loc, bool full_quantity)
10511{
10512 EntityAI entity = SpawnEntity(object_name, loc, ECE_IN_INVENTORY, RF_DEFAULT);
10513 if (entity)
10514 {
10515 bool is_item = entity.IsInherited(ItemBase);
10516 if (is_item && full_quantity)
10517 {
10518 ItemBase item = ItemBase.Cast(entity);
10519 item.SetQuantity(item.GetQuantityInit());
10520 }
10521 }
10522 else
10523 {
10524 ErrorEx("Cannot spawn entity: " + object_name,ErrorExSeverity.INFO);
10525 return NULL;
10526 }
10527 return entity;
10528}
10529
10530void SetupSpawnedItem(ItemBase item, float health, float quantity)
10531{
10532 if (item)
10533 {
10534 if (health > 0)
10535 item.SetHealth("", "", health);
10536
10537 if (item.CanHaveTemperature())
10538 {
10539 item.SetTemperatureDirect(GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_MIDDLE);
10540 if (item.CanFreeze())
10541 item.SetFrozen(false);
10542 }
10543
10544 if (item.HasEnergyManager())
10545 {
10546 if (quantity >= 0)
10547 {
10548 item.GetCompEM().SetEnergy0To1(quantity);
10549 }
10550 else
10551 {
10552 item.GetCompEM().SetEnergy(Math.AbsFloat(quantity));
10553 }
10554 }
10555 else if (item.IsMagazine())
10556 {
10557 Magazine mag = Magazine.Cast(item);
10558 if (quantity >= 0)
10559 {
10560 mag.ServerSetAmmoCount(mag.GetAmmoMax() * quantity);
10561 }
10562 else
10563 {
10564 mag.ServerSetAmmoCount(Math.AbsFloat(quantity));
10565 }
10566
10567 }
10568 else
10569 {
10570 if (quantity >= 0)
10571 {
10572 item.SetQuantityNormalized(quantity, false);
10573 }
10574 else
10575 {
10576 item.SetQuantity(Math.AbsFloat(quantity));
10577 }
10578
10579 }
10580 }
10581}
10582
10583#ifdef DEVELOPER
10584ItemBase _itemBase;//watched item goes here(LCTRL+RMB->Watch)
10585#endif
Param4< int, int, string, int > TSelectableActionInfoWithColor
Param3 TSelectableActionInfo
EWetnessLevel
Определения 3_Game/DayZ/Entities/EntityAI.c:2
bool SetAttachSoundEvent()
void InventoryItemType()
bool SetDetachSoundEvent()
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:34
void ActionManagerBase(PlayerBase player)
Определения ActionManagerBase.c:63
map< typename, ref array< ActionBase_Basic > > TInputActionMap
Определения ActionManagerClient.c:1
void AddAction(typename actionName)
Определения AdvancedCommunication.c:220
void RemoveAction(typename actionName)
Определения AdvancedCommunication.c:252
TInputActionMap m_InputActionMap
Определения AdvancedCommunication.c:137
bool m_ActionsInitialize
Определения AdvancedCommunication.c:138
override void GetActions(typename action_input_type, out array< ActionBase_Basic > actions)
Определения AdvancedCommunication.c:202
void InitializeActions()
Определения AdvancedCommunication.c:190
string Debug()
Определения CachedEquipmentStorageBase.c:29
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:3942
DayZGame GetDayZGame()
Определения DayZGame.c:3944
EActions
Определения EActions.c:2
ERPCs
Определения ERPCs.c:2
PluginAdminLog m_AdminLog
Определения EmoteManager.c:159
const int MIN
Определения EnConvert.c:28
const int MAX
Определения EnConvert.c:27
float GetTemperature()
Определения Environment.c:500
override bool IsExplosive()
Определения ExplosivesBase.c:59
override bool IsPrepareToDelete()
Определения FireplaceBase.c:643
override bool CanHaveTemperature()
Определения FireplaceBase.c:561
class GP5GasMask extends MaskBase ItemBase
proto GizmoApi GetGizmoApi()
Empty
Определения Hand_States.c:14
FindInventoryLocationType
flags for searching locations in inventory
Определения InventoryLocation.c:18
InventoryLocationType
types of Inventory Location
Определения InventoryLocation.c:4
class BoxCollidingParams component
ComponentInfo for BoxCollidingResult.
bool DamageItemInCargo(float damage)
Определения ItemBase.c:6453
static bool HasDebugActionsMask(int mask)
Определения ItemBase.c:5680
bool HidesSelectionBySlot()
Определения ItemBase.c:9413
float m_VarWetMin
Определения ItemBase.c:4937
void SplitItem(PlayerBase player)
Определения ItemBase.c:6908
void CopyScriptPropertiesFrom(EntityAI oldItem)
Определения ItemBase.c:9634
override void InsertAgent(int agent, float count=1)
Определения ItemBase.c:8895
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:8330
static void SetDebugActionsMask(int mask)
Определения ItemBase.c:5685
void SetIsDeploySound(bool is_deploy_sound)
bool IsOpen()
Определения ItemBase.c:9038
void SplitItemToInventoryLocation(notnull InventoryLocation dst)
Определения ItemBase.c:6875
override bool IsHeavyBehaviour()
Определения ItemBase.c:9240
override void SetWetMax()
Определения ItemBase.c:8616
bool IsCoverFaceForShave(string slot_name)
DEPRECATED in use, but returns correct values nontheless. Check performed elsewhere.
Определения ItemBase.c:9451
void ClearStartItemSoundServer()
Определения ItemBase.c:9390
float m_VarWet
Определения ItemBase.c:4934
void ProcessItemTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
Определения ItemBase.c:9481
map< typename, ref ActionOverrideData > TActionAnimOverrideMap
Определения ItemBase.c:3
override void RemoveAllAgentsExcept(int agent_to_keep)
Определения ItemBase.c:8890
static ref map< int, ref array< ref WeaponParticlesOnBulletCasingEject > > m_OnBulletCasingEjectEffect
Определения ItemBase.c:4997
bool CanBeMovedOverride()
Определения ItemBase.c:7600
override void SetWet(float value, bool allow_client=false)
Определения ItemBase.c:8592
ref TIntArray m_SingleUseActions
Определения ItemBase.c:4983
void StartItemSoundServer(int id, int slotId)
Определения ItemBase.c:9358
override void ProcessVariables()
Определения ItemBase.c:9548
ref TStringArray m_HeadHidingSelections
Определения ItemBase.c:5011
float GetWeightSpecialized(bool forceRecalc=false)
Определения ItemBase.c:8423
bool LoadAgents(ParamsReadContext ctx, int version)
Определения ItemBase.c:8956
void UpdateQuickbarShortcutVisibility(PlayerBase player)
To be called on moving item within character's inventory; 'player' should never be null.
Определения ItemBase.c:8806
void OverrideActionAnimation(typename action, int commandUID, int stanceMask=-1, int commandUIDProne=-1)
Определения ItemBase.c:5271
ref array< ref OverheatingParticle > m_OverheatingParticles
Определения ItemBase.c:5009
override float GetTemperatureFreezeThreshold()
Определения ItemBase.c:9584
bool m_IsSoundSynchRemote
Определения ItemBase.c:9742
float m_OverheatingShots
Определения ItemBase.c:5004
void StopItemSoundServer(int id)
Определения ItemBase.c:9378
static void ToggleDebugActionsMask(int mask)
Определения ItemBase.c:5700
void IncreaseOverheating(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:5424
override float GetTemperatureFreezeTime()
Определения ItemBase.c:9608
ref array< int > m_CompatibleLocks
Определения ItemBase.c:5021
bool CanBeCooked()
Определения ItemBase.c:7556
override void CombineItemsClient(EntityAI entity2, bool use_stack_max=true)
Определения ItemBase.c:5767
float m_TemperaturePerQuantityWeight
Определения ItemBase.c:5035
bool m_RecipesInitialized
Определения ItemBase.c:4919
void SplitIntoStackMax(EntityAI destination_entity, int slot_id, PlayerBase player)
Определения ItemBase.c:6546
override float GetTemperatureThawThreshold()
Определения ItemBase.c:9592
override void OnEnergyConsumed()
Определения ItemBase.c:8536
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:8462
override EWetnessLevel GetWetLevel()
Определения ItemBase.c:8656
float GetSingleInventoryItemWeight()
Определения ItemBase.c:8418
ref TIntArray m_InteractActions
Определения ItemBase.c:4985
void MessageToOwnerStatus(string text)
Send message to owner player in grey color.
Определения ItemBase.c:7620
float m_VarQuantity
Определения ItemBase.c:4925
bool CanPlayDeployLoopSound()
Определения ItemBase.c:9753
override float GetWetMax()
Определения ItemBase.c:8626
bool CanBeUsedForSuicide()
Определения ItemBase.c:9720
override void CombineItemsEx(EntityAI entity2, bool use_stack_max=true)
Определения ItemBase.c:7193
void OnItemInHandsPlayerSwimStart(PlayerBase player)
void SetIsHologram(bool is_hologram)
Определения ItemBase.c:5905
void OnSyncVariables(ParamsReadContext ctx)
DEPRECATED (most likely)
Определения ItemBase.c:7774
void DoAmmoExplosion()
Определения ItemBase.c:6388
static ref map< int, ref array< ref WeaponParticlesOnFire > > m_OnFireEffect
Определения ItemBase.c:4996
void SplitIntoStackMaxCargoClient(EntityAI destination_entity, int idx, int row, int col)
Определения ItemBase.c:6732
int GetItemSize()
Определения ItemBase.c:7585
bool m_CanBeMovedOverride
Определения ItemBase.c:4962
override string ChangeIntoOnAttach(string slot)
Определения ItemBase.c:6312
void UpdateOverheating(ItemBase weapon=null, string ammoType="", ItemBase muzzle_owner=null, ItemBase suppressor=null, string config_to_search="")
Определения ItemBase.c:5492
bool CanDecay()
Определения ItemBase.c:9523
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:8303
void SetQuantityMax()
Определения ItemBase.c:8308
override float GetQuantity()
Определения ItemBase.c:8398
int m_ColorComponentR
Определения ItemBase.c:4974
int m_ShotsToStartOverheating
Определения ItemBase.c:5006
override void OnWetChanged(float newVal, float oldVal)
Определения ItemBase.c:8641
void StopOverheating(ItemBase weapon=null, string ammoType="", ItemBase muzzle_owner=null, ItemBase suppressor=null, string config_to_search="")
Определения ItemBase.c:5499
static void PlayFireParticles(ItemBase weapon, int muzzle_index, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:9139
void OnOverheatingDecay()
Определения ItemBase.c:5462
float GetDryingIncrement(string pIncrementName)
Определения ItemBase.c:8574
void SoundSynchRemoteReset()
int m_Cleanness
Определения ItemBase.c:4940
bool HasMuzzle()
Returns true if this item has a muzzle (weapons, suppressors)
Определения ItemBase.c:5600
bool UsesGlobalDeploy()
Определения ItemBase.c:9752
int m_ItemBehaviour
Определения ItemBase.c:4955
override bool CanReleaseAttachment(EntityAI attachment)
Определения ItemBase.c:9111
float m_HeatIsolation
Определения ItemBase.c:4950
float m_VarWetInit
Определения ItemBase.c:4936
override void OnMovedInsideCargo(EntityAI container)
Определения ItemBase.c:5945
void SetCEBasedQuantity()
Определения ItemBase.c:5713
bool m_CanPlayImpactSound
Определения ItemBase.c:4946
override string GetAttachmentSoundType()
Определения ItemBase.c:9314
float GetOverheatingCoef()
Определения ItemBase.c:5519
array< string > GetHeadHidingSelection()
Определения ItemBase.c:9408
void PlayAttachSound(string slot_type)
Plays sound on item attach. Be advised, the config structure may slightly change in 1....
Определения ItemBase.c:9762
override bool IsStoreLoad()
Определения ItemBase.c:8668
int ComputeQuantityUsed(ItemBase other_item, bool use_stack_max=true)
Определения ItemBase.c:7169
bool IsLightSource()
Определения ItemBase.c:5841
bool m_HasQuantityBar
Определения ItemBase.c:4968
void SetResultOfSplit(bool value)
Определения ItemBase.c:7164
void SplitIntoStackMaxCargo(EntityAI destination_entity, int idx, int row, int col)
Определения ItemBase.c:6796
void OnAttachmentQuantityChanged(ItemBase item)
Called on server side when some attachment's quantity is changed. Call super.OnAttachmentQuantityChan...
Определения ItemBase.c:6965
void UpdateAllOverheatingParticles()
Определения ItemBase.c:5527
float GetSoakingIncrement(string pIncrementName)
Определения ItemBase.c:8583
static void StopOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:9219
override float GetStoreLoadedQuantity()
Определения ItemBase.c:8678
int m_LockType
Определения ItemBase.c:5022
const int ITEM_SOUNDS_MAX
Определения ItemBase.c:5027
bool m_CanBeDigged
Определения ItemBase.c:4969
float m_ItemAttachOffset
Определения ItemBase.c:4952
float GetItemModelLength()
Определения ItemBase.c:8685
bool m_ThrowItemOnDrop
Определения ItemBase.c:4960
override bool ReadVarsFromCTX(ParamsReadContext ctx, int version=-1)
Определения ItemBase.c:7919
override void CheckForRoofLimited(float timeTresholdMS=3000)
Roof check for entity, limited by time (anti-spam solution)
Определения ItemBase.c:8971
void Close()
float GetHeatIsolation()
Определения ItemBase.c:8569
void CombineItems(ItemBase other_item, bool use_stack_max=true)
Определения ItemBase.c:7198
void TransferModifiers(PlayerBase reciever)
appears to be deprecated, legacy code
float GetTemperaturePerQuantityWeight()
Used in heat comfort calculations only!
Определения ItemBase.c:9579
bool CanHaveWetness()
Определения ItemBase.c:9536
int m_CleannessMin
Определения ItemBase.c:4942
void TransferAgents(int agents)
transfer agents from another item
Определения ItemBase.c:8904
string IDToName(int id)
Определения ItemBase.c:7767
bool CanBeConsumed(ConsumeConditionData data=null)
Items cannot be consumed if frozen by default. Override for exceptions.
Определения ItemBase.c:9543
float GetHeatIsolationInit()
Определения ItemBase.c:8564
void PlayPlaceSound()
void SetCanBeMovedOverride(bool setting)
Определения ItemBase.c:7607
override bool HasQuantity()
Определения ItemBase.c:8393
float m_VarWetPrev
Определения ItemBase.c:4935
int m_SoundSyncStop
Определения ItemBase.c:5029
bool IsCargoException4x3(EntityAI item)
Определения ItemBase.c:9629
ref TIntArray m_ContinuousActions
Определения ItemBase.c:4984
int GetMuzzleID()
Returns global muzzle ID. If not found, then it gets automatically registered.
Определения ItemBase.c:5609
void LoadParticleConfigOnFire(int id)
Определения ItemBase.c:5294
int m_VarLiquidType
Определения ItemBase.c:4954
int m_QuickBarBonus
Определения ItemBase.c:4956
void PreLoadSoundAttachmentType()
Attachment Sound Type getting from config file.
Определения ItemBase.c:9302
override float GetWetInit()
Определения ItemBase.c:8636
int m_ImpactSoundSurfaceHash
Определения ItemBase.c:4948
int m_SoundSyncPlay
Определения ItemBase.c:5028
int m_MaxOverheatingValue
Определения ItemBase.c:5007
void SetupSpawnedItem(ItemBase item, float health, float quantity)
Определения ItemBase.c:4931
bool m_IsTakeable
Определения ItemBase.c:4959
bool ShouldSplitQuantity(float quantity)
Определения ItemBase.c:6503
static ref map< string, int > m_WeaponTypeToID
Определения ItemBase.c:4999
string GetLockSoundSet()
Определения ItemBase.c:8734
string GetColorString()
Returns item's PROCEDURAL color as formated string, i.e. "#(argb,8,8,3)color(0.15,...
Определения ItemBase.c:8765
array< int > GetValidFinishers()
returns an array of possible finishers
Определения ItemBase.c:9656
void OnAttachmentQuantityChangedEx(ItemBase item, float delta)
Called on server side when some attachment's quantity is changed. Call super.OnAttachmentQuantityChan...
Определения ItemBase.c:6971
class ItemBase extends InventoryItem SpawnItemOnLocation(string object_name, notnull InventoryLocation loc, bool full_quantity)
Определения ItemBase.c:4911
ItemSoundHandler GetItemSoundHandler()
Определения ItemBase.c:9329
override int GetQuantityMin()
Определения ItemBase.c:8382
void SplitIntoStackMaxToInventoryLocationClient(notnull InventoryLocation dst)
Определения ItemBase.c:6711
override int GetQuickBarBonus()
Определения ItemBase.c:5179
override void SetTakeable(bool pState)
Определения ItemBase.c:9284
float m_OverheatingDecayInterval
Определения ItemBase.c:5008
void SetIsPlaceSound(bool is_place_sound)
override void SplitIntoStackMaxClient(EntityAI destination_entity, int slot_id)
Определения ItemBase.c:6523
void HierarchyCheck(out bool hasParent, out bool hasRootAsPlayer, out ItemBase refParentIB)
Определения ItemBase.c:9501
bool CanProcessDecay()
Определения ItemBase.c:9529
void RemoveAudioVisualsOnClient()
Определения Bottle_Base.c:151
void SoundSynchRemote()
static void AddDebugActionsMask(int mask)
Определения ItemBase.c:5690
void PlayDeployLoopSoundEx()
void RemoveLightSourceItem()
Определения ItemBase.c:9645
bool CanRepair(ItemBase item_repair_kit)
Определения ItemBase.c:7571
bool can_this_be_combined
Определения ItemBase.c:4964
EffectSound m_SoundDeploy
Определения ItemBase.c:9739
int m_SoundSyncSlotID
Определения ItemBase.c:5030
int m_Count
Определения ItemBase.c:4930
float GetBaitEffectivity()
generic effectivity as a bait for animal catching
Определения ItemBase.c:9692
float GetDeployTime()
how long it takes to deploy this item in seconds
Определения ItemBase.c:9276
override bool IsSplitable()
Определения ItemBase.c:6490
bool DamageItemAttachments(float damage)
Определения ItemBase.c:6473
override void WriteVarsToCTX(ParamsWriteContext ctx)
Определения ItemBase.c:7883
void ConvertEnergyToQuantity()
Определения ItemBase.c:8551
override void RemoveAllAgents()
Определения ItemBase.c:8885
override void SetQuantityToMinimum()
Определения ItemBase.c:8314
bool m_WantPlayImpactSound
Определения ItemBase.c:4945
override float GetTemperatureThawTime()
Определения ItemBase.c:9616
ref map< int, ref array< ref WeaponParticlesOnOverheating > > m_OnOverheatingEffect
Определения ItemBase.c:4998
int m_ColorComponentG
Определения ItemBase.c:4975
float m_StoreLoadedQuantity
Определения ItemBase.c:4932
void MessageToOwnerAction(string text)
Send message to owner player in yellow color.
Определения ItemBase.c:7638
int m_ColorComponentA
Определения ItemBase.c:4977
int m_VarQuantityInit
Определения ItemBase.c:4927
float GetFilterDamageRatio()
Определения ItemBase.c:5594
override void SetLiquidType(int value, bool allow_client=false)
Определения ItemBase.c:8778
void OnQuantityChanged(float delta)
Called on server side when this item's quantity is changed. Call super.OnQuantityChanged(); first whe...
Определения ItemBase.c:6942
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:8321
bool m_HideSelectionsBySlot
Определения ItemBase.c:5012
bool IsOverheatingEffectActive()
Определения ItemBase.c:5457
void SetIsBeingPlaced(bool is_being_placed)
Определения ItemBase.c:5874
int GetLiquidContainerMask()
Определения ItemBase.c:5811
void SetInventoryLocationToVicinityOrCurrent(EntityAI root, inout InventoryLocation dst)
Определения ItemBase.c:7078
ref Timer m_CheckOverheating
Определения ItemBase.c:5005
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:5505
float GetEnergy()
Определения ItemBase.c:8525
bool CanBeDigged()
Определения ItemBase.c:5890
bool GetActionWidgetOverride(out typename name)
If we need a different (handheld)item action widget displayed, the logic goes in here.
Определения ItemBase.c:9662
bool IsNVG()
Определения ItemBase.c:5822
float GetUnitWeight(bool include_wetness=true)
Obsolete, use GetWeightEx instead.
Определения ItemBase.c:8485
void SetZoneDamageCEInit()
Sets zone damages to match randomized global health set by CE (CE spawn only)
Определения ItemBase.c:9438
bool m_IsDeploySound
Определения ItemBase.c:9741
bool CanEat()
Определения ItemBase.c:7531
static void PlayOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:9179
override bool IsOneHandedBehaviour()
Определения ItemBase.c:9250
void AddLightSourceItem(ItemBase lightsource)
Adds a light source child.
Определения ItemBase.c:9640
bool IsLiquidContainer()
Определения ItemBase.c:5806
FoodStage GetFoodStage()
overridden on Edible_Base; so we don't have to parse configs all the time
Определения ItemBase.c:7551
override float GetSingleInventoryItemWeightEx()
Определения ItemBase.c:8409
void SaveAgents(ParamsWriteContext ctx)
Определения ItemBase.c:8963
override int GetTargetQuantityMax(int attSlotID=-1)
Определения ItemBase.c:8363
int m_CleannessInit
Определения ItemBase.c:4941
float GetDisinfectQuantity(int system=0, Param param1=null)
Определения ItemBase.c:5589
override int GetAgents()
Определения ItemBase.c:8910
int m_VarQuantityMax
Определения ItemBase.c:4929
override bool IsHologram()
Определения ItemBase.c:5885
float GetItemAttachOffset()
Определения ItemBase.c:8694
bool IsPlaceSound()
Определения ItemBase.c:9755
static int GetDebugActionsMask()
Определения ItemBase.c:5675
override int GetLiquidType()
Определения ItemBase.c:8794
void ProcessDecay(float delta, bool hasRootAsPlayer)
Определения ItemBase.c:9518
override bool IsItemBase()
Определения ItemBase.c:7684
void PlayDeploySound()
override bool IsTwoHandedBehaviour()
Определения ItemBase.c:9260
void ExplodeAmmo()
Определения ItemBase.c:6375
bool IsCombineAll(ItemBase other_item, bool use_stack_max=false)
Определения ItemBase.c:7154
float GetProtectionLevel(int type, bool consider_filter=false, int system=0)
Определения ItemBase.c:8984
static void PlayBulletCasingEjectParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:9159
override void OnEnergyAdded()
Определения ItemBase.c:8543
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:5834
EffectSound m_DeployLoopSoundEx
Определения ItemBase.c:9738
override void DeSerializeNumericalVars(array< float > floats)
Определения ItemBase.c:7824
void StopItemDynamicPhysics()
Определения ItemBase.c:9420
bool HasFoodStage()
Определения ItemBase.c:7544
override void SetStoreLoad(bool value)
Определения ItemBase.c:8663
float GetOverheatingValue()
Определения ItemBase.c:5419
bool ContainsAgent(int agent_id)
Определения ItemBase.c:8863
override void AddWet(float value)
Определения ItemBase.c:8611
bool IsLiquidPresent()
Определения ItemBase.c:5801
bool IsFullQuantity()
Определения ItemBase.c:8403
override void EOnContact(IEntity other, Contact extra)
Определения ItemBase.c:6084
void SplitIntoStackMaxHands(PlayerBase player)
Определения ItemBase.c:6847
void SplitIntoStackMaxHandsClient(PlayerBase player)
Определения ItemBase.c:6823
int m_CleannessMax
Определения ItemBase.c:4943
float m_VarStackMax
Определения ItemBase.c:4931
ref Timer m_PhysDropTimer
Определения ItemBase.c:5018
void MessageToOwnerFriendly(string text)
Send message to owner player in green color.
Определения ItemBase.c:7656
override void SetStoreLoadedQuantity(float value)
Определения ItemBase.c:8673
bool m_IsResultOfSplit string m_SoundAttType
distinguish if item has been created as new or it came from splitting (server only flag)
Определения ItemBase.c:4972
void CheckOverheating(ItemBase weapon=null, string ammoType="", ItemBase muzzle_owner=null, ItemBase suppressor=null, string config_to_search="")
Определения ItemBase.c:5440
void UnlockFromParent()
Unlocks this item from its attachment slot of its parent.
Определения ItemBase.c:5755
bool Repair(PlayerBase player, ItemBase item_repair_kit, float specialty_weight)
Определения ItemBase.c:7578
void OnLiquidTypeChanged(int oldType, int newType)
Определения ItemBase.c:8799
void StartOverheating(ItemBase weapon=null, string ammoType="", ItemBase muzzle_owner=null, ItemBase suppressor=null, string config_to_search="")
Определения ItemBase.c:5486
void PlayDeployFinishSound()
bool AllowFoodConsumption()
Определения ItemBase.c:8721
bool m_IsOverheatingEffectActive
Определения ItemBase.c:5003
int m_LiquidContainerMask
Определения ItemBase.c:4953
void ProcessItemWetness(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
Определения ItemBase.c:9456
override int GetCleanness()
Определения ItemBase.c:8716
bool PairWithDevice(notnull ItemBase otherDevice)
Определения ItemBase.c:9667
bool IsDeploySound()
Определения ItemBase.c:9756
static void RemoveDebugActionsMask(int mask)
Определения ItemBase.c:5695
static void UpdateOverheatingParticles(ItemBase weapon, string ammoType, ItemBase muzzle_owner, ItemBase suppressor, string config_to_search)
Определения ItemBase.c:9199
int m_VarQuantityMin
Определения ItemBase.c:4928
void PerformDamageSystemReinit()
Определения ItemBase.c:9426
override void ClearInventory()
Определения ItemBase.c:8504
static int m_LastRegisteredWeaponID
Определения ItemBase.c:5000
ItemBase GetLightSourceItem()
Определения ItemBase.c:9650
void MessageToOwnerImportant(string text)
Send message to owner player in red color.
Определения ItemBase.c:7674
override float GetItemOverheatThreshold()
Определения ItemBase.c:9600
void StopDeployLoopSoundEx()
bool m_CanThisBeSplit
Определения ItemBase.c:4965
override void SerializeNumericalVars(array< float > floats_out)
Определения ItemBase.c:7788
ItemBase SplitIntoStackMaxToInventoryLocationEx(notnull InventoryLocation dst)
Определения ItemBase.c:6762
float m_ItemModelLength
Определения ItemBase.c:4951
bool m_IsHologram
Определения ItemBase.c:4958
static int m_DebugActionsMask
Определения ItemBase.c:4918
void KillAllOverheatingParticles()
Определения ItemBase.c:5555
bool CanBeCookedOnStick()
Определения ItemBase.c:7561
override int GetQuantityMax()
Определения ItemBase.c:8349
void GetRecipesActions(Man player, out TSelectableActionInfoArray outputList)
Определения ItemBase.c:7232
void OnActivatedByTripWire()
bool IsColorSet()
Определения ItemBase.c:8759
override void RemoveAgent(int agent_id)
Определения ItemBase.c:8876
bool m_ItemBeingDroppedPhys
Определения ItemBase.c:4961
override bool CanPutAsAttachment(EntityAI parent)
Определения ItemBase.c:9066
void PlayDetachSound(string slot_type)
Определения ItemBase.c:9798
static ref map< typename, ref TInputActionMap > m_ItemTypeActionsMap
Определения ItemBase.c:4912
void ProcessItemWetnessAndTemperature(float delta, bool hasParent, bool hasRootAsPlayer, ItemBase refParentIB)
Определения ItemBase.c:9729
override bool IsBeingPlaced()
Определения ItemBase.c:5869
int GetQuantityInit()
Определения ItemBase.c:8387
float ComputeQuantityUsedEx(ItemBase other_item, bool use_stack_max=true)
Определения ItemBase.c:7174
bool IsResultOfSplit()
Определения ItemBase.c:7159
bool m_FixDamageSystemInit
Определения ItemBase.c:4963
float m_ImpactSpeed
Определения ItemBase.c:4947
bool m_IsStoreLoad
Определения ItemBase.c:4966
int GetLiquidTypeInit()
Определения ItemBase.c:8789
string GetDeployFinishSoundset()
ItemBase m_LightSourceItem
Определения ItemBase.c:4981
void LockToParent()
Locks this item in it's current attachment slot of its parent. This makes the "locked" icon visible i...
Определения ItemBase.c:5742
override void SplitIntoStackMaxEx(EntityAI destination_entity, int slot_id)
Определения ItemBase.c:6633
int m_AttachedAgents
Определения ItemBase.c:4989
string m_LockSoundSet
Определения ItemBase.c:5024
void LoadParticleConfigOnOverheating(int id)
Определения ItemBase.c:5363
float m_VarQuantityPrev
Определения ItemBase.c:4926
bool IsSoundSynchRemote()
Определения ItemBase.c:9754
bool m_CanShowQuantity
Определения ItemBase.c:4967
override void OnRightClick()
Определения ItemBase.c:7014
int m_ColorComponentB
Определения ItemBase.c:4976
static ref map< typename, ref TActionAnimOverrideMap > m_ItemActionOverrides
Определения ItemBase.c:4914
bool IsActionTargetVisible()
Определения ItemBase.c:9296
override void OnItemAttachmentSlotChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
Определения ItemBase.c:6119
override void EEHitBy(TotalDamageResult damageResult, int damageType, EntityAI source, int component, string dmgZone, string ammo, vector modelPos, float speedCoef)
Определения ItemBase.c:6412
bool m_IsBeingPlaced
Определения ItemBase.c:4957
int NameToID(string name)
Определения ItemBase.c:7761
void ~ItemBase()
Определения ItemBase.c:5640
override void OnWetLevelChanged(EWetnessLevel newLevel, EWetnessLevel oldLevel)
Определения ItemBase.c:8651
void ClearStopItemSoundServer()
Определения ItemBase.c:9396
override string ChangeIntoOnDetach()
Определения ItemBase.c:6336
float m_VarWetMax
Определения ItemBase.c:4938
void SplitIntoStackMaxToInventoryLocation(notnull InventoryLocation dst)
Определения ItemBase.c:6757
int GetLockType()
Определения ItemBase.c:8729
EffectSound m_SoundDeployFinish
Определения ItemBase.c:9736
override float GetWet()
Определения ItemBase.c:8621
EffectSound m_SoundPlace
Определения ItemBase.c:9737
float GetQuantityNormalizedScripted()
Определения ItemBase.c:8335
override void SetCleanness(int value, bool allow_client=false)
Определения ItemBase.c:8703
bool m_IsPlaceSound
Определения ItemBase.c:9740
override float GetWetMin()
Определения ItemBase.c:8631
ref ItemSoundHandler m_ItemSoundHandler
Определения ItemBase.c:5032
override bool KindOf(string tag)
Определения ItemBase.c:7690
void ItemSoundHandler(ItemBase parent)
Определения ItemSoundHandler.c:31
string Type
Определения JsonDataContaminatedArea.c:11
EffectSound m_LockingSound
Определения Land_Underground_Entrance.c:336
string GetDebugText()
Определения ModifierBase.c:71
@ LOWEST
Определения PPEConstants.c:54
void PluginItemDiagnostic()
Определения PluginItemDiagnostic.c:74
PluginBase GetPlugin(typename plugin_type)
Определения PluginManager.c:325
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
int GetID()
Определения ActionBase.c:1335
void OnItemLocationChanged(ItemBase item)
Определения ActionBase.c:974
GetInputType()
Определения ActionBase.c:221
int m_StanceMask
Определения ActionBase.c:25
int m_CommandUIDProne
Определения ActionBase.c:24
int m_CommandUID
Определения ActionBase.c:23
proto native int GetItemCount()
proto native EntityAI GetItem(int index)
float GetEnergyAtSpawn()
Определения ComponentEnergyManager.c:1325
void SetEnergy0To1(float energy01)
Energy manager: Sets stored energy for this device between 0 and MAX based on relative input value be...
Определения ComponentEnergyManager.c:550
float GetEnergyMaxPristine()
Energy manager: Returns the maximum amount of energy this device can store. It's damage is NOT taken ...
Определения ComponentEnergyManager.c:1320
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/DayZ/Entities/Man.c:48
proto native EntityAI GetAttachmentFromIndex(int index)
proto native bool GetCurrentInventoryLocation(out notnull InventoryLocation loc)
returns information about current item location
proto native bool EnumerateInventory(InventoryTraversalType tt, out array< EntityAI > items)
enumerate inventory using traversal type and filling items array
proto native CargoBase GetCargo()
cargo
static proto native EntityAI LocationCreateEntity(notnull InventoryLocation inv_loc, string type, int iSetupFlags, int iRotation)
creates new item directly at location
proto native int AttachmentCount()
Returns count of attachments attached to this item.
proto native bool FindFreeLocationFor(notnull EntityAI item, FindInventoryLocationType flags, out notnull InventoryLocation loc)
FindFreeLocationFor.
proto void SelectObject(Object object)
proto void SelectPhysics(Physics physics)
Определения ItemBase.c:21
proto native bool IsValid()
verify current set inventory location
proto native EntityAI GetParent()
returns parent of current inventory location
proto native int GetSlot()
returns slot id if current type is Attachment
proto native int GetCol()
returns column of cargo if current type is Cargo / ProxyCargo
proto native int GetRow()
returns row of cargo if current type is Cargo / ProxyCargo
bool WriteToContext(ParamsWriteContext ctx)
Определения InventoryLocation.c:507
proto native int GetType()
returns type of InventoryLocation
proto native int GetIdx()
returns index of cargo if current type is Cargo / ProxyCargo
proto native void SetCargo(notnull EntityAI parent, EntityAI e, int idx, int row, int col, bool flip)
sets current inventory location type to Cargo with coordinates (idx, row, col)
proto native bool GetFlip()
returns flip status of cargo
proto native EntityAI GetItem()
returns item of current inventory location
InventoryLocation.
Определения InventoryLocation.c:30
override bool CanDisplayCargo()
Определения TentBase.c:91
override void OnInventoryEnter(Man player)
Определения BarbedWire.c:203
override string GetFoldSoundset()
Определения BaseBuildingBase.c:108
override bool CanPutAsAttachment(EntityAI parent)
Определения ItemBase.c:7
override bool CanReceiveItemIntoCargo(EntityAI item)
Определения TentBase.c:934
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 string GetLoopFoldSoundset()
Определения BaseBuildingBase.c:113
override bool CanMakeGardenplot()
Определения FieldShovel.c:3
override void GetDebugActions(out TSelectableActionInfoArrayEx outputList)
Определения PowerGenerator.c:397
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:409
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 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
Определения ItemBase.c:14
Определения 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 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:40
proto native float GetDamage(string zoneName, string healthType)
override void Refresh()
Определения ChatInputMenu.c:70
void SetCalcDetails(string details)
Определения 3_Game/DayZ/tools/Debug.c:916
void OnRPC(PlayerIdentity sender, int rpc_type, ParamsReadContext ctx)
Определения WrittenNoteData.c:13
const float LOWEST
Определения EnConvert.c:113
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
Serializer ParamsWriteContext
Определения gameplay.c:16
const int DEF_BIOLOGICAL
Определения 3_Game/DayZ/constants.c:515
const int DEF_CHEMICAL
Определения 3_Game/DayZ/constants.c:516
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:712
array< int > TIntArray
Определения EnScript.c:714
void Obsolete(string msg="")
Определения EnScript.c:371
EntityEvent
Entity events for event-mask, or throwing event from code.
Определения EnEntity.c:45
static const float ITEM_TEMPERATURE_NEUTRAL_ZONE_MIDDLE
Определения 3_Game/DayZ/constants.c:811
const int VARIABLE_LIQUIDTYPE
Определения 3_Game/DayZ/constants.c:635
const int VARIABLE_CLEANNESS
Определения 3_Game/DayZ/constants.c:638
const int VARIABLE_COLOR
Определения 3_Game/DayZ/constants.c:637
const int VARIABLE_TEMPERATURE
Определения 3_Game/DayZ/constants.c:633
const int VARIABLE_QUANTITY
Определения 3_Game/DayZ/constants.c:631
const int VARIABLE_WET
Определения 3_Game/DayZ/constants.c:634
const int LIQUID_NONE
Определения 3_Game/DayZ/constants.c:532
static proto float AbsFloat(float f)
Returns absolute value.
const int MENU_INVENTORY
Определения 3_Game/DayZ/constants.c:180
proto native bool dBodyIsDynamic(notnull IEntity ent)
const int SAT_CRAFTING
Определения 3_Game/DayZ/constants.c:456
const int SAT_DEBUG_ACTION
Определения 3_Game/DayZ/constants.c:457
vector GetPosition()
Get the world position of the Effect.
Определения Effect.c:473
static proto string Format(string fmt, void param1=NULL, void param2=NULL, void param3=NULL, void param4=NULL, void param5=NULL, void param6=NULL, void param7=NULL, void param8=NULL, void param9=NULL)
Gets n-th character from string.
const int CALL_CATEGORY_GAMEPLAY
Определения 3_Game/DayZ/tools/tools.c:10
const int CALL_CATEGORY_SYSTEM
Определения 3_Game/DayZ/tools/tools.c:8
proto native int GetColor()

Используется в InventoryItem::ItemBase().